【问题标题】:SQL index slows because of function call由于函数调用,SQL 索引变慢
【发布时间】:2018-06-27 02:42:37
【问题描述】:

有一个 SO 问题 Error matching dates in PDO 我给出了答案并进行了一些交谈。

基本上我说过不要在日期上使用通配符:

SELECT * FROM table where datefiled LIKE '%2018-06%'

改为使用类似的东西(是的,中间也可以):

SELECT * FROM table where MONTH(datefield) = '06' and YEAR(datefield) = '2018

这导致对我的回答发表评论,说他被告知(数据超过 9000 万行):

当您在列上应用函数时,它会避免使用索引进行查找,因为它必须对索引中的所有值应用相同的函数,因此效率会降低。因此需要使用日期边界的技巧。

我对 SQL 实现的搜索算法的理解不是很好,但我知道何时使用和不使用索引(阅读与写作)。以上似乎暗示使用MONTH()YEAR() 函数将不如字符串LIKE 有效。如果评论是关于 BETWEEN 的,我会明白的,但我无法想象LIKE 会因为函数调用而胜出的用例。

如果可以,那是什么用例?

【问题讨论】:

    标签: sql algorithm indexing


    【解决方案1】:

    LIKE 需要将日期转换为字符串。尽管转换是隐式的,但它仍然等同于函数调用并且(通常)阻止使用索引。

    同样,MONTH()YEAR() 是函数调用,它们阻止使用索引。

    相反,只需写一个不等式:

    SELECT t.*
    FROM table t
    WHERE datefield >= '2018-06-01' AND datefield < '2018-07-01'
    

    【讨论】:

    • 所以最终不是LIKE 的表现会优于YEAR()MONTH(),而是因为SQL 可以更有效地使用索引,所以两者的公平性会更快?我对LIKEYEAR()MONTH() 进行了一些测试,后者似乎效率更高。
    • @nerdlyist 。 . .我很惊讶它会更加更有效率,但是对日期部分的操作应该比like 模式匹配更快。我认为查询仍然会读取所有行,这是更大的性能驱动因素。
    • 奇怪的是,LIKE 即使有匹配的数据也返回了空集,并且需要几秒钟而不是以毫秒为单位返回数据的部分。
    • @nerdlyist 。 . .你还没有指定你的数据库。也许您的数据库足够智能,可以将索引用于日期部分。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-05
    • 2019-01-27
    相关资源
    最近更新 更多