【问题标题】:MySQL - Faster method for this complex query?MySQL - 这个复杂查询的更快方法?
【发布时间】:2010-09-23 14:42:31
【问题描述】:

是否有一种资源密集度较低/速度更快的方式来执行此查询(部分基于:This StackOverflow question)。目前,每张表只需要 0.008 秒搜索十几行。

SELECT DISTINCT *
FROM (
(

SELECT DISTINCT ta.auto_id, li.address, li.title, GROUP_CONCAT( ta.tag ) , li.description, li.keyword, li.rating, li.timestamp
FROM tags AS ta
INNER JOIN links AS li ON ta.auto_id = li.auto_id
WHERE ta.user_id =1
AND (
ta.tag LIKE '%query%'
)
OR (
li.keyword LIKE '%query%'
)
GROUP BY li.auto_id
)
UNION DISTINCT (

SELECT DISTINCT auto_id, address, title, '', description, keyword, rating, `timestamp`
FROM links
WHERE user_id =1
AND (
keyword LIKE '%query%'
)
)
) AS total
GROUP BY total.auto_id

非常感谢,

【问题讨论】:

  • 你真的需要 LIKE '%query%' 吗?我认为他们永远不会很快。
  • 是的,因为我正在搜索,除非你知道另一种方式。
  • 我在第一个之后摆脱了差异 - 将时间减半到 0.004
  • 如果你可以做 LIKE 'query%' 这会加快速度,即。以而不是包含查询字符串开头。
  • 很遗憾,这是不可能的,但还是谢谢你——你的建议将来可能会对我有所帮助。

标签: mysql


【解决方案1】:

我希望查询优化器会为您执行此操作,但您可能希望在执行联接之前尝试按 user_id 对标签进行选择,以防万一出现第一个子查询。这可能会减少您可能必须连接的行数。您可能还希望在 auto_id AND user_ID 上有索引。

SELECT DISTINCT *
FROM (
   (SELECT ta.auto_id, li.address, li.title, GROUP_CONCAT( ta.tag ),
           li.description, li.keyword, li.rating, li.timestamp
    FROM (SELECT auto_id, tag FROM tags WHERE user_id = 1) AS ta
         INNER JOIN links AS li ON ta.auto_id = li.auto_id
         WHERE (ta.tag LIKE '%query%') OR (li.keyword LIKE '%query%')
    GROUP BY li.auto_id
   )
   UNION (
       SELECT auto_id, address, title, '', description, keyword, rating, `timestamp`
       FROM links
       WHERE user_id = 1 AND (keyword LIKE '%query%')
   )
) AS total
GROUP BY total.auto_id

【讨论】:

  • 谢谢!我预计这也会更快,但它是 0.008 而不是现有的 0.004(并且索引已经到位)
【解决方案2】:

如果您可以使用 MyISAM 表格格式,请尝试在 ta.tag 和 li.keyword 上使用 full-text index and search

【讨论】:

    【解决方案3】:

    在具有数十行的表上进行测试不一定会告诉您是否存在性能问题。 DBMS 可能会根据表的大小使用不同的策略。

    在大型数据集上尝试此操作,以更好地评估是否存在问题以及问题的严重程度。

    【讨论】:

      【解决方案4】:

      如果没有表定义很难确定,但您可以将查询改写为从 LINKS 到 TAGS 的更简单的左连接:

      select li.auto_id, 
             address, 
             title, 
             group_concat(ta.tag), 
             description,  
             keyword, 
             rating,  
             timestamp 
      from links li  
      left join tags ta ON ta.auto_id = li.auto_id  
      where li.user_id = 1 and ( keyword like '%query%' or ta.tag like '%query%' ) 
      group by li.auto_id;
      

      逻辑可能需要加强以处理关键字或 ta.tag 中的空值 - 取决于表定义。

      【讨论】:

        【解决方案5】:

        % 通配符可能会阻止您的查询使用索引,尤其是领先的索引 - 搜索 'cat%' 仍然可以使用索引,但 '%cat%' 不能。除非您的数据集很小,否则这可能是致命的。

        我还会检查 OR 逻辑是否给您带来麻烦 - 我不确定优化器是否能够分别优化关键字和标签条件。如果它不能,它会放弃并暴力破解它。

        重新迭代其他一些 cmets:

        • 使用更大的数据集进行测试
        • 先尝试此查询的各个组件(其中大约有三个单独的查询),然后再尝试将它们全部组合在一起。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-01-13
          • 2012-04-16
          • 2015-01-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多