查询优化(MySql / Sql):将函数移出where子句

时间:2017-07-26 15:31:05

标签: mysql sql query-optimization where-clause

更新:对于读这篇文章的人来说,正如@dnoeth所述,索引在查询时间方面有很大的不同。在某些情况下,它会将行扫描减少到1行。您只需要选择最适合您的索引风格。 Clustered vs Non Clustered

索引示例:

E.g: create index ix_descr on my_db.media (description asc)

我有一个需要很长时间才能运行的查询,它在where子句中有很多功能。优化查询的最佳方法是什么?

将函数移出where子句并用连接等替换它们?

我在下面给出了一些简单的例子,图2 3 是我的最佳尝试,让我知道你的想法。

注意*这些不是我正在使用的实际功能,我使用dbo.DecryptBlob(m.mediaId)等。我选择使用下面的函数来使问题更容易掌握。

图1。)

SELECT 
    description, id
FROM
    my_db.media
where 
    length(description) = 10
    and description like "S%"
    and trim(left(m.description,2)) = 'St'

可能的优化

图2。)(使用加入和分组)

SELECT
    m.description, m.mediaId
FROM
    my_db.media m
        inner JOIN
    my_db.media m1 ON length(m.description) = 10 
        and m.description like "S%"
        and trim(left(m.description,2)) = 'St'
group by m.mediaId

图3。)(使用join和distinct)

SELECT distinct
    m.description, m.mediaId
FROM
    my_db.media m
        inner JOIN
    my_db.media m1 ON length(m.description) = 10 
        and m.description like "S%"
        and trim(left(m.description,2)) = 'St'

2 个答案:

答案 0 :(得分:0)

您的开始评论我的短语为"请勿隐藏功能内的索引列,优化工具无法找到它以使用INDEX。"

and description like "S%"
and trim(left(m.description,2)) = 'St'

相同
and description LIKE "St%"

有了它,INDEX(description)将很好地工作。检查长度= 10是次要的,而不是真正的问题。它会做一个"范围"扫描该指数。 (如果您不是指' 2' St',那么我的评论可能不会适用。)

TRIM - 清除输入,而不是在SELECT期间尝试清除输入。

在这种情况下,使用JOIN会显示事情。

这是错误的"在group by m.mediaId列表中未指定mediaId的情况下执行SELECT。所以,我不知道你在图2中的目标。

答案 1 :(得分:0)

如果您的应用程序经常选择描述的长度,您应该考虑添加一个包含描述长度的列并在其上创建索引。