Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用System.Data.SQLite(C)进行SQLite查询比使用SQLiteStudio要慢得多_Sqlite - Fatal编程技术网

使用System.Data.SQLite(C)进行SQLite查询比使用SQLiteStudio要慢得多

使用System.Data.SQLite(C)进行SQLite查询比使用SQLiteStudio要慢得多,sqlite,Sqlite,我有一个在同一个表上运行多个联接的查询。它在SessionID上连接,SessionID是一个键,不表示表中的列,但通过子字符串操作生成为新列。请参见下面的查询代码 因此,我无法主动在SessionID上创建索引,因为相关表日志中不存在该列 但是,当我在SQLiteStudio v3.1.1中运行查询时,查询运行得相当快。在SQLiteStudio中运行explain查询计划时,我确实看到以下输出: 1 0 0 SEARCH TABLE logs USING INDEX i_Logs

我有一个在同一个表上运行多个联接的查询。它在SessionID上连接,SessionID是一个键,不表示表中的列,但通过子字符串操作生成为新列。请参见下面的查询代码

因此,我无法主动在SessionID上创建索引,因为相关表日志中不存在该列

但是,当我在SQLiteStudio v3.1.1中运行查询时,查询运行得相当快。在SQLiteStudio中运行explain查询计划时,我确实看到以下输出:

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=?)
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=?)
id  parent  notused detail
3   0   0   MATERIALIZE 2
7   3   0   SEARCH TABLE logs USING INDEX i_Logs (Code=?)
44  0   0   MATERIALIZE 3
48  44  0   SEARCH TABLE logs USING INDEX i_Logs (Code=?)
92  0   0   SEARCH TABLE logs USING INDEX i_Logs (Code=?)
112 0   0   SEARCH SUBQUERY 2 AS b USING AUTOMATIC COVERING INDEX (SessionID=?)
140 0   0   SEARCH SUBQUERY 3 AS c USING AUTOMATIC COVERING INDEX (SessionID=?)
157 0   0   USE TEMP B-TREE FOR GROUP BY
259 0   0   USE TEMP B-TREE FOR ORDER BY
正如我们所看到的,SQLite正在使用一个自动覆盖索引SessionID

当通过System.Data.SQLite从MyC对同一个数据库运行相同的查询时,查询速度会显著降低50倍左右

在C中运行explain查询计划时,我确实看到以下输出:

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=?)
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=?)
id  parent  notused detail
3   0   0   MATERIALIZE 2
7   3   0   SEARCH TABLE logs USING INDEX i_Logs (Code=?)
44  0   0   MATERIALIZE 3
48  44  0   SEARCH TABLE logs USING INDEX i_Logs (Code=?)
92  0   0   SEARCH TABLE logs USING INDEX i_Logs (Code=?)
112 0   0   SEARCH SUBQUERY 2 AS b USING AUTOMATIC COVERING INDEX (SessionID=?)
140 0   0   SEARCH SUBQUERY 3 AS c USING AUTOMATIC COVERING INDEX (SessionID=?)
157 0   0   USE TEMP B-TREE FOR GROUP BY
259 0   0   USE TEMP B-TREE FOR ORDER BY
请注意,没有使用自动覆盖索引

我尝试使用Analyze并为SQLite连接显式地设置automatic_index=true,但它没有影响查询计划

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版本3.24.0升级SQLite Studio之后,我看到的解释查询计划输出与System.Data.SQLite SQLit v3.27.0版本相同。注意:自动覆盖索引部件现在也丢失了


非常有趣:我将查询转换为视图并从myview运行select*后,查询速度非常快。解释查询计划现在具有以下输出:

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=?)
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=?)
id  parent  notused detail
3   0   0   MATERIALIZE 2
7   3   0   SEARCH TABLE logs USING INDEX i_Logs (Code=?)
44  0   0   MATERIALIZE 3
48  44  0   SEARCH TABLE logs USING INDEX i_Logs (Code=?)
92  0   0   SEARCH TABLE logs USING INDEX i_Logs (Code=?)
112 0   0   SEARCH SUBQUERY 2 AS b USING AUTOMATIC COVERING INDEX (SessionID=?)
140 0   0   SEARCH SUBQUERY 3 AS c USING AUTOMATIC COVERING INDEX (SessionID=?)
157 0   0   USE TEMP B-TREE FOR GROUP BY
259 0   0   USE TEMP B-TREE FOR ORDER BY
我不知道为什么在我使用视图时EQP发生了变化,但我现在非常高兴,因为它工作得非常好,速度非常快:-


非常感谢@Carlos Cavero格式化我的代码。

非常有趣:我将查询转换为视图并从myview运行select*后,查询速度非常快。解释查询计划现在具有以下输出:

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=?)
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=?)
id  parent  notused detail
3   0   0   MATERIALIZE 2
7   3   0   SEARCH TABLE logs USING INDEX i_Logs (Code=?)
44  0   0   MATERIALIZE 3
48  44  0   SEARCH TABLE logs USING INDEX i_Logs (Code=?)
92  0   0   SEARCH TABLE logs USING INDEX i_Logs (Code=?)
112 0   0   SEARCH SUBQUERY 2 AS b USING AUTOMATIC COVERING INDEX (SessionID=?)
140 0   0   SEARCH SUBQUERY 3 AS c USING AUTOMATIC COVERING INDEX (SessionID=?)
157 0   0   USE TEMP B-TREE FOR GROUP BY
259 0   0   USE TEMP B-TREE FOR ORDER BY
我不知道为什么在我使用视图时EQP发生了变化,但我现在非常高兴,因为它工作得非常好,速度非常快:-


非常感谢@Carlos Cavero对我的代码进行格式化。

这两个程序使用的sqlite是什么版本?它们可能不一样,尽管基于EQP输出,它们都是较旧的版本。你能重新格式化你的帖子,使select可读,而不是一条很长的行吗?嗨@Shawn。运行命令时,选择sqlite_version;-我看到了以下输出:SQLiteStudio:3.15.0 C代码:3.27.2我正在使用System.Data.SQLite 1.0.110和SQLiteStudio v3.1.1.Hi@Shawn。我更新了SQLite Studio,现在在运行select SQLite_version;时看到以下输出:3.24.0此外,自更新以来,解释查询计划现在看起来与我在C3.27.2查询计划中看到的完全相同:0 0使用索引I_logs Code=?0 0使用索引i_日志代码=?0 0使用索引i_日志代码=?注意:使用自动覆盖索引SessionID=?现在这里也缺少了部分。您可以找到在线工具来很好地将SQL格式化为人类可读的格式。在这两个版本之间的变更日志中可能会有一些东西适用,但您现在的查询仍然是一个无法读取的混乱,我不能确定。两个程序使用的sqlite版本可能不同,虽然基于EQP的输出都是旧的。你能重新格式化你的帖子,使选择是可读的,而不是一个巨大的长行吗?嗨@Shawn。运行命令时,选择sqlite_version;-我看到了以下输出:SQLiteStudio:3.15.0 C代码:3.27.2我正在使用System.Data.SQLite 1.0.110和SQLiteStudio v3.1.1.Hi@Shawn。我更新了SQLite Studio,现在在运行select SQLite_version;时看到以下输出:3.24.0此外,自更新以来,解释查询计划现在看起来与我在C3.27.2查询计划中看到的完全相同:0 0使用索引I_logs Code=?0 0使用索引i_日志代码=?0 0使用索引i_日志代码=?注意:使用自动覆盖索引SessionID=?现在这里也缺少了部分。您可以找到在线工具来很好地将SQL格式化为人类可读的格式。在这两个版本之间的变更日志中可能有一些东西是适用的,但是您现在的查询仍然是一个无法阅读的混乱,我不能确定。