我的查询性能有问题。我有以下内容:
SELECT DISTINCT anuncios.id, precios.precio
FROM anuncios
LEFT JOIN precios ON ( (
precios.idcentroanuncio = anuncios.idcentro
AND anuncios.tipoubicacion = 'centropropio'
AND precios.tipocentroanuncio = 'centro'
) )
GROUP BY anuncios.id
LIMIT 0 , 30
花费0.001 seg。另一方面,我有这个,非常相似:
SELECT DISTINCT anuncios.id, precios.precio
FROM anuncios
LEFT JOIN precios ON (
(
precios.idcentroanuncio = anuncios.id
AND anuncios.tipoubicacion = 'centropropio'
AND precios.tipocentroanuncio = 'centro'
) )
GROUP BY anuncios.id
LIMIT 0 , 30
也花费相同的时间,或多或少。问题是当我将两个查询合并到这个中时:
SELECT DISTINCT anuncios.id, precios.precio
FROM anuncios
LEFT JOIN precios ON ( (
precios.idcentroanuncio = anuncios.idcentro
AND anuncios.tipoubicacion = 'centropropio'
AND precios.tipocentroanuncio = 'centro'
)
OR (
precios.idcentroanuncio = anuncios.id
AND anuncios.tipoubicacion = 'centropropio'
AND precios.tipocentroanuncio = 'centro'
) )
GROUP BY anuncios.id
LIMIT 0 , 30
这里执行时间乘以100.
Theese都是表格解释:
Precios:
+-------------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| usuario | varchar(40) | NO | MUL | NULL | |
| tipocentroanuncio | varchar(50) | NO | | NULL | |
| idcentroanuncio | int(10) unsigned | NO | MUL | NULL | |
| unidades | float | NO | | NULL | |
| tipounidades | varchar(15) | NO | | NULL | |
| precio | float | NO | | NULL | |
| otrosdatosprecio | varchar(100) | NO | | NULL | |
| principal | int(1) unsigned | NO | | NULL | |
+-------------------+------------------+------+-----+---------+----------------+
anuncios:
+------------------+------------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+------------------+------+-----+---------------------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_ |
+------------------+------------------+------+-----+---------------------+------
这是查询的解释:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE anuncios ALL NULL NULL NULL NULL 1048578 Using temporary; Using filesort
1 SIMPLE precios index idcentroanuncio idcentroanuncio 156 NULL 30 Using index
我做错了什么?结合两个独立运行的查询,这次增加是合乎逻辑的吗?
答案 0 :(得分:1)
是。您已经了解到or
可以真正搞乱执行计划。请尝试使用union
:
SELECT a.id, p.precio
FROM anuncios a LEFT JOIN
precios p
ON p.idcentroanuncio = a.idcentro AND
a.tipoubicacion = 'centropropio' AND
p.tipocentroanuncio = 'centro'
UNION
SELECT a.id, p.precio
FROM anuncios a LEFT JOIN
precios p
ON p.idcentroanuncio = a.id AND
a.tipoubicacion = 'centropropio' AND
p.tipocentroanuncio = 'centro'
LIMIT 0 , 30;
一些笔记,然后是更好的查询。首先,当您distinct
时,您不需要group by
。其次,此版本不需要group by
或distinct
,因为union
负责使值不同。
为了表现,您可以采取不同的路线。试试这个:
select p.idcentroanuncio, p.price
from precios p
where p.tipocentroanuncio = 'centro' and
(exists (select 1
from annuncios a
where p.idcentroanuncio = a.id and a.tipoubicacion = 'centropropio'
) or
exists (select 1
from annuncios a
where p.idcentroanuncio = a.idcentro and a.tipoubicacion = 'centropropio'
)
);
这可以消除对distinct
的需要。子查询可以各自利用索引:annuncios(id, tipoubicacion)
和annuncios(idcentro, tipoubicacion)
。