【问题标题】:Python sqlite3 not using index with LIKEPython sqlite3 不使用带有 LIKE 的索引
【发布时间】:2018-12-16 01:47:47
【问题描述】:

我有一个单列表,我通过两种方式查询:

  • SELECT * FROM sequences WHERE seqs="blablabla"
  • SELECT * FROM sequences WHERE seqs LIKE "blablabla%"

为了让这些查询使用索引,我似乎需要两个索引(每个查询类型一个),例如:

  • CREATE INDEX test_nocol ON sequences(seqs) 第一个查询。
  • CREATE INDEX seqs_index ON sequences(seqs COLLATE NOCASE) 用于第二个查询。

这一切都很好,但后来我添加了 python3 的 sqlite3 模块,然后开始在那里查询,它适用于原始字符串,但是当我使用参数绑定时,COLLATE 索引突然不再使用:

>>> sql = 'explain query plan\n select seqs from sequences where seqs="blabla"'
>>> c3.execute(sql).fetchall()
[(0, 0, 0, 'SEARCH TABLE sequences USING COVERING INDEX test_nocol (seqs=?)')]
>>> sql = 'explain query plan\n select seqs from sequences where seqs=?'
>>> c3.execute(sql, ('hahahah',)).fetchall()
[(0, 0, 0, 'SEARCH TABLE sequences USING COVERING INDEX test_nocol (seqs=?)')]
>>> sql = 'explain query plan\n select seqs from sequences where seqs like "hahahah%"'
>>> c3.execute(sql).fetchall()
[(0, 0, 0, 'SEARCH TABLE sequences USING COVERING INDEX seqs_index (seqs>? AND seqs<?)')]
>>> sql = 'explain query plan\n select seqs from sequences where seqs like ?'
>>> c3.execute(sql, ('hahahah',)).fetchall()
[(0, 0, 0, 'SCAN TABLE sequences')]

我在这里做错了什么?由于这是一个序列化后端而不是 webapp 数据库,我猜使用原始字符串时的威胁不那么严重,但我更愿意使用正确的 SQL 格式。

【问题讨论】:

    标签: python indexing sqlite


    【解决方案1】:

    documentation 说:

    如果右侧是绑定到字符串的parameter,则仅当包含表达式的prepared statement 使用sqlite3_prepare_v2()sqlite3_prepare16_v2() 编译时才会尝试此优化。如果右侧是 parameter 并且语句是使用 sqlite3_prepare()sqlite3_prepare16() 准备的,则不会尝试 LIKE 优化。

    旧版本的 pysqlite 模块使用sqlite3_prepare()

    【讨论】:

    • 谢谢,使用 PyPI 中的 pysqlite 而不是 python std 库 sqlite3 (v.2.6.0) 模块解决了这个问题。不幸的是,我在 python3 上并且 pysqlite 包不可用(还)。 stackoverflow.com/a/23414147/1271862
    猜你喜欢
    • 2023-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-27
    相关资源
    最近更新 更多