如何使用多个INNER JOIN加速查询

时间:2009-10-13 16:15:53

标签: sql database ms-access sqlite

我一直在努力将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从命令提示符运行,都需要相同的时间。

所以我的问题如下:

  1. SQLite是否未针对多个INNER JOIN语句进行优化?
  2. 我在查询中做了一些明显愚蠢的事情(因为我是SQLite的新手),这让它变得如此之慢?
  3. 并且在任何人提出完全不同的技术之前,我不能切换。我的选择是MS-Access或SQLite。 :)

    更新 为SQLite数据库中的每个列分配INDEX将查询时间从8分钟缩短到大约6秒。感谢Larry Lustig解释为什么需要INDEXing。

3 个答案:

答案 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;

等......

正确索引是一个难题,可以轻松地将查询速度提高一倍,三倍或更多。