我有一个运行速度非常慢的SQL查询,我很困惑为什么。查询是:
SELECT DISTINCT(c.ID),c.* FROM `content` c
LEFT JOIN `content_meta` cm1 ON c.id = cm1.content_id
WHERE 1=1
AND c.site_id IN (14)
AND c.type IN ('a','t')
AND c.status = 'visible'
AND (c.lock = 0 OR c.site_id = 14)
AND c.level = 0
OR
(
( c.site_id = 14
AND cm1.meta_key = 'g_id'
AND cm1.meta_value IN ('12','13','7')
)
OR
( c.status = 'visible'
AND (
(c.type = 'topic' AND c.parent_id IN (628,633,624))
)
)
)
ORDER BY c.date_updated DESC LIMIT 20
内容表有大约1250行,内容元表有大约3000行。这不是很多数据,我不太确定是什么导致它运行这么慢。任何想法/意见将不胜感激。
谢谢!
答案 0 :(得分:1)
你的条款是否正确?您正在制作一系列AND语句,之后您正在执行OR。
不正确的是:
AND (c.lock = 0 OR c.site_id = 14)
AND (
( ... )
OR
( ... )
)
如果它确实是正确的,您可以考虑更改结构或在脚本或过程中处理结果。
答案 1 :(得分:0)
最后可能与你的“OR”子句有关...你的前面的索引尽可能被索引使用,但是你可以在最后输入这个巨大的OR条件另一个。不知道更多的底层内容,我会调整内部有一个UNION,这样每个实体都可以利用自己的索引,获得合格的CID,然后加入最终结果。
select
c2.*
from
( select distinct
c.ID
from
`content` c
where
c.site_id in (14)
and c.type in ('a', 't' )
and c.status = 'visible'
and c.lock in ( 0, 14 )
and c.level = 0
UNION
select
c.ID
from
`content` c
where
c.status = 'visible'
and c.type = 'topic'
and c.parent_id in ( 628, 633, 624 )
UNION
select
c.ID
from
`content` c
join `content_meta` cm1
on c.id = cm1.content_id
AND cm1.meta_key = 'g_id'
AND cm1.meta_value in ( '12', '13', '7' )
where
c.site_id = 14 ) PreQuery
JOIN `content` c2
on PreQuery.cID = c2.cID
order by
c2.date_updated desc
limit
20
我会确保内容表在(site_id,type,status)上有另一个索引(parent_id,type,status)
和元表,(content_id,meta_key,meta_value)上的索引