1. INDEXED BY 是如何工作的
INDEXED BY 短语强制SQLite 查询计划器在DELETE、SELECT或UPDATE语句上使用特定的命名索引。INDEXED BY 短语是 SQLite 扩展,不能移植到其他 SQL 数据库引擎。
“INDEXED BY index-name ”短语指定必须使用命名索引才能在前面的表中查找值。如果index-name不存在或不能用于查询,则SQL语句准备失败。“NOT INDEXED”子句指定在访问前面的表时不得使用索引,包括由 UNIQUE 和 PRIMARY KEY 约束创建的隐含索引。但是,即使指定了“NOT INDEXED”, rowid 仍可用于查找条目。
某些 SQL 数据库引擎提供非标准的“提示”机制,可用于为查询优化器提供有关特定语句应使用哪些索引的线索。SQLite 的 INDEXED BY 子句 不是提示机制,不应该这样使用。INDEXED BY 子句不给优化器提示使用哪个索引;它为优化器提供了使用哪个索引的要求。如果查询优化器无法使用 INDEXED BY 子句指定的索引,则查询将因错误而失败。
INDEXED BY 子句不适用于调整查询的性能。INDEXED BY 子句的目的是在架构更改(例如删除或创建索引)导致时间敏感查询的查询计划更改时引发运行时错误。INDEXED BY 子句旨在帮助检测回归测试期间不需要的查询计划更改。应用程序开发人员被警告在应用程序设计、实现、测试和调整期间省略所有 INDEXED BY 的使用。如果要使用 INDEXED BY,则应在开发过程的最后“锁定”设计时将其插入。
2.另见
查询规划器清单描述了应用程序开发人员应遵循的步骤,以帮助解决查询规划器问题。请注意,使用 INDEXED BY 是最后的手段,只有在所有其他措施都失败时才使用。
一元“+”运算符 可用于取消索引使用 WHERE 子句中的术语。小心使用一元 + 有时可以帮助防止查询计划器选择一个糟糕的索引而不限制它使用一个特定的索引。仔细放置一元 + 运算符是控制查询使用哪些索引的更好方法。
sqlite3_stmt_status() C /C++ 接口连同 SQLITE_STMTSTATUS_FULLSCAN_STEP和SQLITE_STMTSTATUS_SORT动词可用于在运行时检测 SQL 语句何时未有效使用索引。许多应用程序可能更喜欢使用sqlite3_stmt_status()接口来检测索引滥用,而不是此处描述的 INDEXED BY 短语。