gpt4 book ai didi

sql - 如何优化MySQL查询(分组和顺序)

转载 作者:可可西里 更新时间:2023-11-01 07:14:11 25 4
gpt4 key购买 nike

大家好,我有一个查询需要优化。它有效,但它是一只狗,性能明智。

它是这样写的:

SELECT  *
FROM (
SELECT *
FROM views
WHERE user_id = '1'
ORDER BY
page DESC
) v
GROUP BY
v.session

我正在跟踪不同页面的浏览量,我想知道每个 session 的最高页面,以便了解他们点击了多远(他们需要一直查看每个页面直到最后)在任何给定的 session 中。

基本上,我要做的是在 GROUP 之前对结果进行排序。上述实现的代价是巨大的。

谁能教我如何做到这一点?谢谢大家!

更新:

解释:

"1" "PRIMARY"   "<derived2>"    "ALL"   \N  \N  \N  \N  "3545"  "Using temporary; Using filesort"

"2" "DERIVED" "views" "index" \N "page" "5" \N "196168" "Using where"

架构:

ID       int(8) unsigned  (NULL)     NO      PRI     (NULL)   auto_increment  select,insert,update,references         
page int(8) (NULL) YES MUL (NULL) select,insert,update,references
user_id int(8) (NULL) YES (NULL) select,insert,update,references
session int(8) (NULL) YES (NULL) select,insert,update,references
created datetime (NULL) NO select,insert,update,references

索引信息:

views            0  PRIMARY              1  ID           A               196008    (NULL)  (NULL)          BTREE    

views 1 page 1 page A 259 (NULL) (NULL) YES BTREE

最佳答案

I'm tracking views to different pages, and I want to know the highest page per session, in order to know how far they've clicked through (they're required to view every page all the way to the end) in any given session.

在分组前排序是一种非常不可靠的方法。

MySQL 扩展了 GROUP BY 语法:您可以在 SELECTORDER BY 子句中使用未分组和未聚合的字段.

在这种情况下,page 的随机值是每个 session 的输出。

Documentation明确指出你永远不应该对它到底是哪个值做出任何假设:

Do not use this feature if the columns you omit from the GROUP BY part are not constant in the group. The server is free to return any value from the group, so the results are indeterminate unless all values are the same.

但是,实际上,返回扫描的第一行中的值。

由于您在子查询中使用了 ORDER BY page DESC,因此该行恰好是每个 session 具有最大 page 的行。

你不应该依赖它,因为这个行为没有记录,如果在下一个版本中会返回一些其他行,它不会被认为是一个错误。

但你甚至不必做这种卑鄙的把戏。

只需使用聚合函数:

SELECT  MAX(page)
FROM views
WHERE user_id = '1'
GROUP BY
session

这是有据可查的干净方式来做你想做的事。

(user_id, session, page) 上创建复合索引,以便查询运行得更快。

如果您需要表中的所有列,而不仅仅是聚合列,请使用以下语法:

SELECT  v.*
FROM (
SELECT DISTINCT user_id, session
FROM views
) vo
JOIN views v
ON v.id =
(
SELECT id
FROM views vi
WHERE vi.user_id = vo.user_id
AND vi.session = vo.session
ORDER BY
page DESC
LIMIT 1
)

这假设 idviews 上的 PRIMARY KEY

关于sql - 如何优化MySQL查询(分组和顺序),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1201296/

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