MySQL - 这个复杂查询的更快的方法?

时间:2008-11-22 16:19:09

标签: mysql

执行此查询的资源密集型/更快的方式是否较少(部分基于: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

非常感谢,

5 个答案:

答案 0 :(得分:2)

我希望查询优化器会为您执行此操作,但您可能希望在执行连接之前尝试通过user_id执行select on标记,以防万一在第一个子查询中。这可能会减少您必须加入的行数。您可能还希望在auto_id和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

答案 1 :(得分:1)

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

答案 2 :(得分:1)

在包含数十行的表上测试此信息并不一定会告诉您是否存在性能问题。 DBMS可以根据表的大小使用不同的策略。

在大数据集上尝试这一点,以便更好地评估是否存在问题以及它是多么严重。

答案 3 :(得分:0)

没有表定义很难确定,但您可以将查询重新定义为从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中的空值 - 具体取决于表定义。

答案 4 :(得分:0)

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

我还要检查OR逻辑是否会给您带来麻烦 - 我不确定优化器是否能够单独优化关键字和标记条件。如果它不能,它会放弃并蛮力。

重新考虑其他一些评论:

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