我有一个像这样的属性表
CREATE TABLE attributes (
attribute_id INT,
product_id INT,
random INT,
UNIQUE KEY (attribute_id,random,product_id),
KEY (product_id)
);
random
是在插入项上为洗牌产品计算的随机整数(可以满足我的需求)。有一些自联接查询,例如
SELECT DISTINCT x.product_id
FROM attibutes x
INNER JOIN attributes y ON x.product_id=y.product_id
INNER JOIN attributes z ON x.product_id=z.product_id
WHERE x.attribute_id IN (20000085,20000090) AND
y.attribute_id IN (10000007) AND
z.attribute_id IN (30000050,30000040,30000012)
LIMIT 0,100;
如您所见,我想选择在每个数字范围内至少具有一个属性的产品。MySQL非常聪明,它会根据UNIQUE键的选择性为第一次查询选择表别名。正如预期的那样,由于random
UNIQUE键,结果按列顺序排序。但是我如何建议MySQL恢复命令?添加ORDER BY x.random DESC
时,MySQL可能会使用filesort进行排序,因为如果它对y
基本查询使用表别名(由于属性ID 10000007的更好的选择性),则必须使用alias的UNIQUE键x
。问题是:我不知道MySQL会使用哪个别名(由查询优化器决定)。那么如何指定订单方向呢?
(我想指出该表包含约6000万行,因此在响应时间中是否使用filesort会很重要)
您可能会检查此版本是否更快:
SELECT a.product_id
FROM attibutes a
WHERE a.attribute_id IN (20000085, 20000090, 10000007, 30000050, 30000040, 30000012)
GROUP BY a.product_id
HAVING SUM(a.attribute_id IN (20000085, 20000090) ) > 0 AND
SUM(a.attribute_id IN (10000007) ) > 0 AND
SUM(a.attribute_id IN (30000050, 30000040, 30000012) ) > 0
ORDER BY a.rand
LIMIT 0, 100;
的费用GROUP BY
应与的大致相同SELECT DISTINCT
。您仍然会产生按随机数排序的开销,但是有时这种表述从性能角度来看是可行的。
编辑:
如果将随机数放在产品表中,则可能会执行以下操作:
select p.*
from products p
where exists (select 1 from attributes a where p.product_id = a.product_id and a.attribute_id IN (20000085, 20000090) ) and
exists (select 1 from attributes a where p.product_id = a.product_id and a.attribute_id IN (10000007) ) and
exists (select 1 from attributes a where p.product_id = a.product_id and a.attribute_id IN (30000050, 30000040, 30000012) )
order by p.rand
limit 5;
嗯,如果您将随机数存储在产品表中,则可以将join
其输入查询中,并在中使用它order by
。那也许也行。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句