Гость
Форумы / SQLite [игнор отключен] [закрыт для гостей] / Скорость поиска по ID / 5 сообщений из 5, страница 1 из 1
07.02.2017, 06:25
    #39399755
amsdev
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Скорость поиска по ID
Приветствую !

Есть простая таблица:

Код: plsql
1.
2.
3.
4.
CREATE TABLE List1 (
    ID       INTEGER       PRIMARY KEY AUTOINCREMENT NOT NULL,
    Name   VARCHAR 
);



Которая фактически используется как key-value хранилище. В таблице около 7 миллионов записей. Файл базы данных лежит на SSD.

Необходимо делать больше число запросов вида SELECT Name WHERE ID=X и как-то меня скорость не устраивает. На моей машине (Core I7 3.3 ггц + SSD)получается в районе 1000-1200 поисков в секунду !

Это нормально или как ? По идее ведь должно быть раз в 10 быстрее или я ошибаюсь ?

з.ы. Доступ к БД из Delphi через компоненты LiteDAC от DevArt.

А у вас какая средняя скорость поиска по ключу ?
...
Рейтинг: 0 / 0
07.02.2017, 21:48
    #39400463
VSVLAD
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Скорость поиска по ID
amsdev,

Для сгенерированной таблицы в 7 млн строк, значения поля "ID" от 1 .. 7 000 000, значение поля "Name" 4 буквенные слова. Получились такие результаты, в .NET:

Код: powershell
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
БД хранится на обычном HDD: чтение порядка 26 тыс значений в секунду

Test 1: 1089 мс
Test 2: 1021 мс
Test 3: 1014 мс
Test 4: 1023 мс

БД хранится в RAM: 26 тыс значений за 240 мс.

Test 1: 254 мс
Test 2: 238 мс
Test 3: 237 мс
Test 4: 241 мс



Тест
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
Public Function TestSelect() As Long
        Dim sb As New StringBuilder
        Dim sw As New Stopwatch()

        Dim sqlCn As New SQLiteConnection("Data source=D:\Test.db")
        sqlCn.Open()

        Dim sqlCmd = sqlCn.CreateCommand
        sqlCmd.CommandText = $"SELECT Name From List1 Where Id = @ID"

        Dim sqlParam As New SQLiteParameter("@ID", DbType.Int32) 'Делаем через параметры, выжимаем всю скорость
        sqlCmd.Parameters.Add(sqlParam)

        sw.Start()

        For I = 1 To 26000
            sqlParam.Value = I
            sb.AppendLine(sqlCmd.ExecuteScalar()) 'Полезная нагрузка, читаем результаты в StringBuilder
        Next

        sw.Stop()
        Return sw.ElapsedMilliseconds
    End Function
...
Рейтинг: 0 / 0
08.02.2017, 00:32
    #39400506
amsdev
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Скорость поиска по ID
Да, похоже тормозит LiteDAC не понятно почему. Через другой sqlite враппер получается не меньше 50к поисков в секунду. Попробую его профайлером....
...
Рейтинг: 0 / 0
08.02.2017, 13:32
    #39400821
PPA
PPA
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Скорость поиска по ID
amsdev,

Может LiteDAC не делает биндинг через sqlite
а выполняет подстановку параметра в sql перед исполнением?
...
Рейтинг: 0 / 0
08.02.2017, 15:50
    #39401028
amsdev
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Скорость поиска по ID
C LiteDAC не удалось разобраться почему тормозит, максимум что из него смог выжать это 2000 поисков в секунду по primary key полю.

В качестве решения подошел опенсорсный Sqlite враппер от mORMot - www.synopse.info он гораздо тоньше и ближе к апи Sqlite чем LiteDAC, к тому же у автора-француза бзик на оптимизацию (в хорошем смысле). С ним получается 100 000 поисков в секунду (и в районе 200 000 если открыть базу данных в режиме Exclusive). С другой стороны, это не TDataSet, что не так удобно. Точнее там есть Датасет, эмулирующий обычный (и работающий на порядки быстрее), но он немного отличается там сям, а код переписывать лень. Поэтому для критичных мест использую mORMot, а для обычных - LiteDAC. LiteDAC в целом не плох и если не делать миллионов выборок в цикле то работает вполне сносно, хотя 300 баксов отданых за него жалко.

Пример использования враппера mORMot для поиска, может кому пригодится:

uses SynSQLite3, SynDBSqlite3, SynDB;

// С начала где-то при старте проги нужно один раз сделать:

FreeAndNil(sqlite3);
sqlite3:=TSQLite3LibraryDynamic.Create('c:\sqlite3.dll'); // sqlite3 это глобальная переменная из SynSQlite3
// там можно использовать и статическую линковку, но мне нужна внешняя т.к. она собрана с особыми параметрами.

// сама выборка
var
SqDb:TSQLDataBase;
Qry:TSQLDBSQLite3ConnectionProperties;
QryRes:ISQLDBRows;
begin
SqDb:=TSQLDataBase.Create('c:\mydb.db','',SQLITE_OPEN_READWRITE or SQLITE_OPEN_CREATE,10000); // 10000 это размер кэша
Qry:=TSQLDBSQLite3ConnectionProperties.Create(SqDb);
QryRes:=Qry.Execute(StringToUTF8('SELECT ID FROM MyTable WHERE ID=?'),[IDtoSearch]);
if QryRes.Step then
ShowMessage('Found');
Qry.Free;
SqDb.Free;
QryRes:=nil; // обязательно, иначе будет AV ! Это штатно по справке.
end;
...
Рейтинг: 0 / 0
Форумы / SQLite [игнор отключен] [закрыт для гостей] / Скорость поиска по ID / 5 сообщений из 5, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]