У меня есть запрос, который запускает несколько объединений в одной таблице. Он присоединяется к SessionID
, который является ключом, который не представляет столбец в таблице, но генерируется как new column
с помощью операций подстроки (см. Также код запроса ниже).
Соответственно, я не могу заранее создать индекс для SessionID, потому что этот столбец не существует в соответствующей таблице Logs
.
Однако, когда я выполняю запрос в SQLiteStudio (v3.1.1), запрос выполняется довольно быстро. Когда я запускаю план запроса объяснения в SQLiteStudio, я вижу следующий вывод:
1 0 0 SEARCH TABLE logs USING INDEX i_Logs (Code=?)
2 0 0 SEARCH TABLE logs USING INDEX i_Logs (Code=?)
0 0 0 SEARCH TABLE logs USING INDEX i_Logs (Code=?)
0 1 1 SEARCH SUBQUERY 1 AS b USING AUTOMATIC COVERING INDEX (SessionID=?)
0 2 2 SEARCH SUBQUERY 2 AS c USING AUTOMATIC COVERING INDEX (SessionID=?)
Как мы видим, SQLite использует автоматический индекс покрытия SessionID.
При выполнении того же запроса из моего C # через System.Data.SQLite для той же базы данных запрос значительно медленнее (примерно в 50 раз).
Когда я запускаю план запроса объяснения в C #, я вижу следующий вывод:
7 0 0 SEARCH TABLE logs USING INDEX i_Logs (Code=?)
14 0 0 SEARCH TABLE logs USING INDEX i_Logs (Code=?)
48 0 0 SEARCH TABLE logs USING INDEX i_Logs (Code=?)
Обратите внимание, что не используется автоматический индекс покрытия.
Я попытался использовать Analyze и также явно установил automatic_index = true для соединения SQLite, но это не повлияло на план запроса.
Запрос SQLite:
select a.username, a.PSMID, a.PSMHost, a.AccountName, A.TargetHost, a.TargetUser,
Case When info2 Not like '%DataBase=%' Then '' Else substr(info2, instr(info2, 'DataBase=') +9, (instr(info2, ';Dst') +- instr(info2, 'DataBase=') - 9)) End as TargetDataBase, a.ConnectionComponent, a.StartTime,
Case when c.time is not null then c.time else b.EndTime end as EndTime,
Case when c.SessionDuration is not null then c.SessionDuration else b.SessionDuration end as SessionDuration,
Case When c.RequestReason not like '%PSMSR169E%' and c.RequestReason != '' then 'Yes' else 'No' End as ErrorOccurred,
Case When c.RequestReason like '%PSMSR169E%' Then 'Yes' Else 'No' End as DurationElapsed, c.RequestReason As Message
from (SELECT info2, time as StartTime, username, replace(info1,'Root\','') as AccountName,
Case When info2 not like '%;DataBase=%' Then substr(info2, instr(info2, 'ApplicationType=') +16 , instr(info2, ';Dst') -17) Else substr(info2, instr(info2, 'ApplicationType=') +16 , instr(info2, ';DataBase=') -17)
End as ConnectionComponent, substr(info2, instr(info2, 'DstHost=') +8, (instr(info2, ';Pro') +- instr(info2, 'DstHost=') - 8)) as TargetHost, substr(info2, instr(info2, 'User=') +5, length(info2) - instr(info2, 'User=') -5) as TargetUser,
substr(info2, instr(info2, 'PSMID=') +6, (instr(info2, ';Session') - instr(info2, 'PSMID=') - 6)) as PSMID,
substr(info2, instr(info2, 'SessionID=') +10, (instr(info2, ';Src') - instr(info2, 'SessionID=') -10)) as SessionID,
substr(info2, instr(info2, 'SrcHost=') +8, (instr(info2, ';User') - instr(info2, 'SrcHost=') -8)) as PSMHost,
Null as SessionDuration from logs
where code in (300) and info2 != 0) a left join (select time as EndTime,
substr(info2, instr(info2, 'SessionDuration=') +16, (instr(info2, ';SessionID') - instr(info2, 'SessionDuration=') - 16)) as SessionDuration,
substr(info2, instr(info2, 'SessionID=') +10, (instr(info2, ';Src') - instr(info2, 'SessionID=') -10)) as SessionID
from logs
where code in (302) and info2 != 0) b on a.SessionID = b.SessionID left join (Select 'Yes' as PSMDisconnectFailed, time,
substr(info2, instr(info2, 'SessionID=') +10, (instr(info2, ';Src') - instr(info2, 'SessionID=') -10)) as SessionID,
substr(info2, instr(info2, 'SessionDuration=') +16, (instr(info2, ';SessionID') - instr(info2, 'SessionDuration=') - 16)) as SessionDuration, RequestReason
from logs where code in (303) and info2 != 0) c on a.SessionID = C.SessionID
У кого-нибудь есть идеи по дальнейшему устранению неполадок / расследованию этой проблемы?
РЕДАКТИРОВАТЬ # 1: я использую следующую команду для установления соединения в моем коде C #:
public static SQLiteConnection connectToDB()
{
dbConnection = new SQLiteConnection("Data Source = data\\LOGS.db; Version = 3;");
dbConnection.Open();
return dbConnection;
}
Редактирование # 2: После обновления SQLite Studio (теперь использующей SQLite версии 3.24.0) я вижу тот же вывод плана запроса объяснения, что и в версии System.Data.SQLite SQLit v3.27.0. Примечание: «ИНДЕКС АВТОМАТИЧЕСКОГО ПОКРЫТИЯ» теперь также отсутствует.
7 0 0 SEARCH TABLE logs USING INDEX i_Logs (Code=?)
14 0 0 SEARCH TABLE logs USING INDEX i_Logs (Code=?)
48 0 0 SEARCH TABLE logs USING INDEX i_Logs (Code=?)