我一直在努力将ms-access文件切换到SQLite文件,以满足我简单的数据库需求;通常的原因:文件较小,开销较小,开源等等。
阻止我进行切换的一件事似乎是SQLite缺乏速度。对于简单的SELECT查询,SQLite似乎与MS-Access一样好或更好。使用多个INNER JOIN语句的相当复杂的SELECT查询会出现问题:
SELECT DISTINCT
DESCRIPTIONS.[oCode] AS OptionCode,
DESCRIPTIONS.[descShort] AS OptionDescription
FROM DESCRIPTIONS
INNER JOIN tbl_D_E ON DESCRIPTIONS.[oCode] = tbl_D_E.[D]
INNER JOIN tbl_D_F ON DESCRIPTIONS.[oCode] = tbl_D_F.[D]
INNER JOIN tbl_D_H ON DESCRIPTIONS.[oCode] = tbl_D_H.[D]
INNER JOIN tbl_D_J ON DESCRIPTIONS.[oCode] = tbl_D_J.[D]
INNER JOIN tbl_D_T ON DESCRIPTIONS.[oCode] = tbl_D_T.[D]
INNER JOIN tbl_Y_D ON DESCRIPTIONS.[oCode] = tbl_Y_D.[D]
WHERE ((tbl_D_E.[E] LIKE '%')
AND (tbl_D_H.[oType] ='STANDARD')
AND (tbl_D_J.[oType] ='STANDARD')
AND (tbl_Y_D.[Y] = '41')
AND (tbl_Y_D.[oType] ='STANDARD')
AND (DESCRIPTIONS.[oMod]='D'))
在MS-Access中,此查询在大约2.5秒内执行。在SQLite中,它需要超过8 分钟。无论是从VB代码运行查询还是使用sqlite3.exe从命令提示符运行,都需要相同的时间。
所以我的问题如下:
并且在任何人提出完全不同的技术之前,我不能切换。我的选择是MS-Access或SQLite。 :)
更新 为SQLite数据库中的每个列分配INDEX将查询时间从8分钟缩短到大约6秒。感谢Larry Lustig解释为什么需要INDEXing。
答案 0 :(得分:11)
根据要求,我将之前的评论作为实际答案重新发布(当我第一次发布评论时,由于某种原因,我无法将其作为答案发布):
MS Access非常积极地代表您为列编制索引,而SQLite将要求您显式创建所需的索引。因此,Access可能为您索引[描述]或[D],但SQLite中缺少这些索引。我没有在SQLite中使用大量JOIN活动的经验。我在一个Django项目中使用它,数据量相对较小,并没有检测到任何性能问题。
答案 1 :(得分:6)
您是否存在参照完整性问题?我问,因为你有不必要的联接的印象,所以我重新写了你的查询:
SELECT DISTINCT
t.[oCode] AS OptionCode,
t.[descShort] AS OptionDescription
FROM DESCRIPTIONS t
JOIN tbl_D_H h ON h.[D] = t.[oCode]
AND h.[oType] = 'STANDARD'
JOIN tbl_D_J j ON j.[D] = t.[oCode]
AND j.[oType] = 'STANDARD'
JOIN tbl_Y_D d ON d.[D] = t.[oCode]
AND d.[Y] = '41'
AND d.[oType] ='STANDARD'
WHERE t.[oMod] = 'D'
答案 2 :(得分:0)
如果DESCRIPTIONS和tbl_D_E有多行扫描,那么oCode和D应该被编入索引。看一下这里的示例,看看如何索引并告诉它有多少行扫描(http://www.siteconsortium.com/h/p1.php?id=mysql002)。
这可能会解决它..
CREATE INDEX ocode_index ON DESCRIPTIONS(oCode)使用BTREE; CREATE INDEX d_index ON tbl_D_E(D)使用BTREE;
等......
正确索引是一个难题,可以轻松地将查询速度提高一倍,三倍或更多。