mysql - 如何指定多个自连接的排序顺序

标签 mysql sql

我有一个像这样的属性表

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 键的选择性。正如预期的那样,由于 UNIQUE 键,结果按列random 的顺序排序。 但是我怎样才能建议 MySQL 恢复顺序呢?添加 ORDER BY x.random DESC 时,MySQL 可能会使用文件排序进行排序,因为如果它使用表别名 y 进行基本查询(因为属性 ID 10000007 具有更好的选择性) )它必须使用别名 x 的 UNIQUE 键。问题是:我不知道MySQL 使用哪个别名(这是由其查询优化器决定的)。那么如何指定订单方向呢?

(我想指出该表包含大约 6000 万行,因此是否使用文件排序对响应时间影响很大)

最佳答案

您可以检查此版本是否更快:

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;

嗯,如果您将随机数存储在产品表中,您只需将其加入到您的查询中,并在order by中使用它。这也可能有效。

关于mysql - 如何指定多个自连接的排序顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29866923/

相关文章:

mysql - SQL Join 三张表保持不重叠的空值

asp.net - 将静态数据存储在数据库或文件系统中

php - 更新两个 MySQL 数据库

php - 探索数据建模(如何将合理的数据库组合在一起)

多表表连接的Mysql查询问题

php - SQL 表可以有符号链接(symbolic link)或别名吗?

mysql - 查找与同一列中的多个值匹配的不同元素

mysql 按最大 id 分组并左连接另一个表

mysql - 使用命令行客户端格式化从 excel 到 mysql 的输入

python - 如何将元组列表转换为字符串?