针对基于一组ID(即不同的主键)查询sqlite表,我使用以下语句(示例基于 Chinook Database ):
SELECT * FROM Customer WHERE CustomerId IN (1,2,3,8,20,35)
然而,我的实际ID列表可能会变得相当大(>1000)。因此,我想知道使用 IN
语句的这种方法是否是最有效的,或者是否有更好/优化的方式根据一组主键查询sqlite表。
针对基于一组ID(即不同的主键)查询sqlite表,我使用以下语句(示例基于 Chinook Database ):
SELECT * FROM Customer WHERE CustomerId IN (1,2,3,8,20,35)
然而,我的实际ID列表可能会变得相当大(>1000)。因此,我想知道使用 IN
语句的这种方法是否是最有效的,或者是否有更好/优化的方式根据一组主键查询sqlite表。
因为你编写的语句没有任何指示 SQLite 如何查找所需行,因此“优化”这个概念实际上不存在——没有什么可优化的。规划检索数据的最佳算法是 SQLite 查询优化器的任务。
有些数据库的查询优化器存在问题可能会导致性能问题,但我不认为 SQLite 在查找包含大量 IN 列表的简单查询时会遇到任何麻烦。只有在发现性能问题时才需要尝试引导查询优化器到另一种执行计划。
IN (expression-list)
如果可用,会使用索引。
除此之外,我无法从中获得任何保证,所以下面的内容都需要进行性能测量。
方案一:如何传递expression-list
... WHERE CustomerID in (?,?,?,?,?,?,?,?,?,?....)
,这比硬编码的值更容易从预定义字符串构建)。可以避免整数→字符串→整数的转换,但默认参数数量限制为999。可以通过SQLITE_LIMIT_VARIABLE_NUMBER
来增加,但可能会导致过多的分配。轴2:语句优化
如果相同的表达式列表在多个针对不同CustomerIDs
的查询中使用,以下预处理语句或许可以帮助:
如果每个查询的表达式列表都不同,那么最好还是让SQLite自己处理。以下方法或许可以改进:
(根据我对SQLite的经验,我预计它的性能应该与原来相当或略有下降)
轴 3 向 Richard 提问
SQLite 邮件列表(是的,我知道,这项技术甚至比旋转电话还要古老!)非常活跃,通常会提供出色的建议,包括 SQLite 的作者。有 90% 的机会有人会认为你在提问之前应该“先测量”,还有 10% 的机会有人会给你详细的见解。
expr.c
中有这样的描述:无论是 'x IN(SELECT...)' 还是 'x IN(<exprlist>)' 表达式,处理方式都是相同的。一个临时表会被填充,其中包含来自 SELECT 或 <exprlist> 的结果的索引键。 - Jeff Lockhart