【问题标题】:Optimization and scalability of an annidate MySQL queryannidate MySQL 查询的优化和可扩展性
【发布时间】:2014-09-08 06:02:43
【问题描述】:

我有这个 annidate 查询:

SELECT [U_ProdId], [U_CompDesc]
FROM [dbo].[@BE_CMPNTS]
WHERE [U_CompId] IN (
    SELECT DISTINCT [U_CompId]
    FROM [dbo].[@BE_CHARS] Carat JOIN [dbo].[@BE_CHARVL] CarVal ON Carat.U_CharValueId = CarVal.Code
    WHERE CarVal.Name LIKE '%Manico%' 
) AND [U_CompId] IN (
    SELECT DISTINCT [U_CompId]
    FROM [dbo].[@BE_CHARS] Carat JOIN [dbo].[@BE_CHARVL] CarVal ON Carat.U_CharValueId = CarVal.Code
    WHERE CarVal.Name LIKE '%Nero%'  
) AND [U_CompId] IN (
    SELECT DISTINCT [U_CompId]
    FROM [dbo].[@BE_CHARS] Carat JOIN [dbo].[@BE_CHARVL] CarVal ON Carat.U_CharValueId = CarVal.Code
    WHERE CarVal.Name LIKE '%Pelle%'  
)

出于可扩展性目的,我会优化此查询。

如果我有少量 Carval.Name 选项,则 annidate 查询很快。但是,如果我有越来越多的选项可以附加到查询中,我的计算成本就会非常高。

如果有办法,我该如何优化这个 annidate 查询?我必须使用一些加入?如何?谢谢。

【问题讨论】:

    标签: sql sql-server join query-optimization scalability


    【解决方案1】:

    试试这个作为开始:

    SELECT
          [U_ProdId]
        , [U_CompDesc]
    FROM [dbo].[@BE_CMPNTS]
    WHERE [U_CompId] IN (
                SELECT /* DISTINCT */ /* see notes on this below */
                      [U_CompId]
                FROM [dbo].[@BE_CHARS] Carat
                      JOIN [dbo].[@BE_CHARVL] CarVal
                                  ON Carat.U_CharValueId = CarVal.Code
                WHERE CarVal.Name LIKE '%Manico%'
                      AND CarVal.Name LIKE '%Nero%'
                      AND CarVal.Name LIKE '%Pelle%'
          )
    

    我尽量避免的三件事

    1, % ... %

    双端通配符停止使用索引。对于正在搜索的那些条件,将进行表扫描。 (= 慢)

    2、IN(子查询)

    IN() 非常方便,也许太方便了很多人在不需要或明智的时候会使用它们。当这些括号内的项目数量不大时,IN() 非常适合使用,但是一旦该子查询开始返回大量的值,它就会变得越来越慢。当子查询的结果是“未知”或“可能非常大”时,我不喜欢使用 IN()。这里是未知的 - 所以我不喜欢它。

    就我无法判断的规模而言,它们可能都还可以。

    3,不同

    这是一项昂贵的操作,尽管针对单个字段这还不错。但是,在 IN() 中使用时,此查询实际上并不需要它

    这是使用 IN() 的完全有效的语法:

    select * from abc where id IN(1,1,1,1,1,1,2,2,2,2,2,2)

    虽然这对人类来说似乎是无稽之谈,但将列表减少到“独特”所需的努力可能会超过好处。如果子查询的规模不是太大,那么我建议删除不同的。这里没有黄金法则,它取决于子查询的规模。最好继续使用 distinct - 或不使用。


    您也许可以将 IN() 替换为内部联接,但如果不了解更多有关表和数据的信息,我不会那么自信地说它会更好。

    【讨论】:

    • 对不起你是对的应该是AND的,我会改变查询。关于 NEED for distinct 我不能同意, IN() 不要求你有一个不同的列表。在您的情况下,使用 distinct 可能会更快,但这并不总是如此。
    猜你喜欢
    • 2021-12-11
    • 1970-01-01
    • 2011-06-12
    • 1970-01-01
    • 2022-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多