【发布时间】:2021-10-02 13:52:20
【问题描述】:
我有两个表的查询——matchoverview
id、home_id、away_id、日期、季节、结果
匹配属性
id、game_id、attribute_id、attribute_value
我的查询
select m.id from matchOverview m
join matchAttributes ma on ma.match_id=m.id and ma.attribute_id in (3,4,5,6)
group by m.id
having sum(case when ma.attribute_id in (3,4)
then ma.attribute_value end) > 3
or sum(case when ma.attribute_id in (5,6)
then ma.attribute_value end) > 3;
返回所有属性 3 和 4 或 5 和 6 之和大于 3 的匹配 id。
这个特定的查询返回 900k 行,不出所料,在 phpmyadmin 中这个查询需要花费大量时间,因为我想它需要将结果格式化为一个表格,但它将查询计时为 0.0113 秒。
然而,当我通过 PHP 进行此查询时,它需要 15 秒,如果我将查询更改为 LIMIT 到只有 100 个结果,它几乎立即运行,让我相信唯一的可能性是正在传输的数据量是什么正在减慢它。
但是通过网络传输 1M 4 字节整数真的需要 15 秒吗?
是进一步限制查询以使其返回更少结果的唯一解决方案吗?
编辑
我的查询的解释结果
id select_type table type key key key_len ref rows Extra
1 SIMPLE m index PRIMARY PRIMARY 4 NULL 2790717 Using index
1 SIMPLE ma ref match,attribute match 4 opta_matches2.m.id 2 Using where
我如何计时我的 SQL 查询
$time_pre = microtime(true);
$quer = $db->query($sql);
$time_post = microtime(true);
$exec_time = $time_post - $time_pre;
来自慢查询日志的数据
# Thread_id: 15 Schema: opta_matches2 QC_hit: No
# Query_time: 15.594386 Lock_time: 0.000089 Rows_sent: 923962 Rows_examined: 15688514
# Rows_affected: 0 Bytes_sent: 10726615
我可以处理 15 秒的查询,因为这是数据在网络上移动所需的时间,但如果可以优化查询或我的表,那是最好的解决方案
行数不是问题,如下查询
select m.id from matchOverview m
join matchAttributes ma on ma.match_id=m.id and ma.attribute_id in (1,2,3,4)
group by m.id
having sum(case when ma.attribute_id in (3,4)
then ma.attribute_value end) > 8
and sum(case when ma.attribute_id in (1,2)
then ma.attribute_value end) = 0;
只返回 24 行,但也需要大约 15 秒
【问题讨论】:
-
如果 phpMyAdmin 告诉您查询只用了 0.0113 秒,那么剩下的 15 秒就渲染了该页面
-
是的,我承认这个事实,我的问题是为什么我的 php 代码需要 15 秒才能运行,而无需进行任何渲染
-
永远没有理由向用户显示 990k 行。所以想想“用户需要什么?”。如果您确实需要向他显示所有数据,请使用分页或其他类型的过滤将要查询的行数减少到 100 以下。
-
@ClausBönnhoff 用户看不到这么多行,ID 用于内部计算,这又需要 15 秒,并且没有数据被绘制到屏幕上。正如您所提到的,是过滤 100k+ 行以下的唯一解决方案?意味着问题是通过网络发送这么多数据?
-
ids 用于内部计算 - 那么为什么不在数据库中这样做并返回 its 结果 - 将 900k 行拉出当您实际上并不需要时的数据库是查询性能 101;您已经测试并诊断出行数是原因。
标签: php mysql sql sql-optimization