gpt4 book ai didi

mysql - 使用 GROUP BY、ORDER BY 和 GROUP_CONCAT 进行索引

转载 作者:行者123 更新时间:2023-12-01 02:43:52 25 4
gpt4 key购买 nike

已解决 见下文

我正在尝试同时使用 GROUP BYORDER BY在我检索按难度排序的数据的查询中。我必须使用 GROUP BY因为GROUP CONCAT由于某些表(例如“lookup_peripheral”)将多个值链接到同一个键 (content_id)。我理解为什么 MYSQL 在执行此任务时不能使用索引,因为 GROUP BY 和 ORDER BY 语句不共享相同的字段。但是,我正在寻找不需要一天即可检索结果的替代解决方案。

如果我省略 GROUP BYORDER BY子句,则数据库使用索引,但结果要么缺少所有外围设备,要么未按难度排序。

我在 FROM 中使用了“lookup_difficulty”表所以我可以使用该索引对结果进行排序。 lookup_xxxxx表存储每个允许的值,然后是其他表,例如 peripheral通过 content_id 将提交链接到值。一切引用提交content_id . content表包含基本信息,例如成员 ID、姓名等。

如果我的帖子不够清楚,我深表歉意。

mysql> describe peripheral;
+------------------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------------+----------+------+-----+---------+-------+
| peripheral_id | int(2) | NO | PRI | NULL | |
| peripheral | char(30) | NO | | NULL | |
| peripheral_total | int(5) | NO | | NULL | |
+------------------+----------+------+-----+---------+-------+

mysql> select * from peripheral;
+---------------+-----------------+------------------+
| peripheral_id | peripheral | peripheral_total |
+---------------+-----------------+------------------+
| 1 | periph 1 | 0 |
| 2 | periph 2 | 1 |
| 3 | periph 3 | 3 |
+---------------+-----------------+------------------+

:
mysql> describe lookup_peripheral;
+---------------+---------+------+------+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+---------+------+------+---------+-------+
| content_id | int(10) | NO | INDEX| NULL | |
| peripheral_id | int(2) | NO | | NULL | |
+---------------+---------+------+------+---------+-------+


mysql> mysql> select * from lookup_peripheral;
+------------+---------------+
| content_id | peripheral_id |
+------------+---------------+
| 74 | 2 |
| 74 | 5 |
| 75 | 2 |
| 75 | 5 |
| 76 | 3 |
| 76 | 4 |
+------------+---------------+

以下不是在 lookup_difficulty 上使用索引,而是使用表排序和临时表。
SELECT group_concat(DISTINCT peripheral.peripheral) as peripheral, content.member, .....
FROM (lookup_difficulty)
LEFT OUTER JOIN lookup_peripheral ON lookup_difficulty.content_id = lookup_peripheral.content_id
LEFT OUTER JOIN peripheral ON peripheral.peripheral_id = lookup_peripheral.peripheral_id
.....
LEFT OUTER JOIN programmer ON programmer.programmer_id = lookup_programmer.programmer_id
LEFT OUTER JOIN lookup_programming_language ON lookup_difficulty.content_id = lookup_programming_language.content_id

GROUP BY lookup_difficulty.content_id
ORDER BY lookup_dfficulty.difficulty_id
LIMIT 30

最终目标是使用连接的正确外围设备检索按难度排序的结果。我想我需要一个子查询来实现这一点。

编辑:下面的答案:

弄清楚了。我做了我怀疑我必须做的事情,即添加子查询。由于MYSQL每个表只能使用一个索引,我无法 GROUP BYSORT BY一起用于我的特定设置。相反,我添加了另一个查询,该查询将使用不同表上的另一个索引将外围设备组合在一起。这是我在 SELECT 中添加的内容上面的声明:
(SELECT group_concat(DISTINCT peripheral.peripheral) as peripheral
FROM lookup_peripheral
LEFT OUTER JOIN peripheral ON peripheral.peripheral_id = lookup_peripheral.peripheral_id
WHERE lookup_difficulty.content_id = lookup_peripheral.content_id
GROUP BY lookup_peripheral.content_id
LIMIT 1) as peripheral

我用了 LEFT OUTER因为有些条目没有任何外围设备。对于大多数表的 40k 行数据库,在 400MHz 处理器上的总查询时间现在为 0.02 秒,128MB 100Hz RAM。
EXPLAIN现在给我一个 USING INDEXlookup_difficulty table 。我添加了这个来实现:
ALTER TABLE `pictuts`.`lookup_difficulty` DROP PRIMARY KEY ,
ADD PRIMARY KEY ( `difficulty_id` , `content_id` )

编辑 2
我注意到使用分页的偏移量较大时,页面加载速度会慢很多。您可能在其他网站上也遇到过这种情况。幸运的是,正如 Peter Zaitsev 所指出的,有一种方法可以避免这种情况。 .这是我更新的片段,用于实现 30K 或 0 偏移量的相同计时:
FROM 
SELECT lookup_difficulty.content_id, lookup_difficulty.difficulty_id
FROM lookup_difficulty
LIMIT '.$offset.', '.$per_page.'
) ld

现在只需添加 ld.whatever到每个 JOIN制作完成,您就拥有了!我的查询现在看起来一团糟,但至少它是优化的。我认为没有人会在阅读这篇文章时走到这一步......

最佳答案

输入 Justin 的答案,这样这个问题就会从未回答的列表中消失:

弄清楚了。我做了我怀疑我必须做的事情,即添加子查询。由于 MYSQL 每个表只能使用一个索引,因此我无法针对我的特定设置将 GROUP BY 和 SORT BY 组合在一起。相反,我添加了另一个查询,该查询将使用不同表上的另一个索引将外围设备组合在一起。这是我在上面的 SELECT 语句中添加的内容:

(SELECT group_concat(DISTINCT p.peripheral) as peripheral
FROM lookup_peripheral lp
LEFT JOIN peripheral p ON p.peripheral_id = lp.peripheral_id
WHERE ld.content_id = lp.content_id
GROUP BY lp.content_id
LIMIT 1) as peripheral

我使用了 LEFT OUTER,因为有些条目没有任何外围设备。对于大多数表的 40k 行数据库,在 400MHz 处理器上的总查询时间现在为 0.02 秒,100Hz RAM 为 128MB。

EXPLAIN 现在给了我一个用于 lookup_difficulty 表的 USING INDEX。我添加了这个来实现:
ALTER TABLE pictuts.lookup_difficulty DROP PRIMARY KEY ,
ADD PRIMARY KEY ( difficulty_id , content_id )

编辑 2 我注意到使用分页偏移较大时,页面加载速度会慢很多。您可能在其他网站上也遇到过这种情况。幸运的是,正如 Peter Zaitsev 所指出的那样,有一种方法可以避免这种情况。这是我更新的片段,用于实现 30K 或 0 偏移量的相同计时:
FROM 
SELECT ld.content_id, ld.difficulty_id
FROM lookup_difficulty ld
LIMIT '.$per_page.' OFFSET '.$offset.'
) ld

现在只需将 ld.whatever 添加到每个 JOIN 中,就可以了!我的查询现在看起来一团糟,但至少它是优化的。我认为没有人会在阅读这篇文章时走到这一步......

关于mysql - 使用 GROUP BY、ORDER BY 和 GROUP_CONCAT 进行索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7381828/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com