某些参数的SQL查询非常慢(MySQL)

问题描述 投票:1回答:2

我正在制作PHP后端API,该API在MySQL数据库上执行查询。这是查询:

SELECT * FROM $TABLE_GAMES WHERE 
 ($GAME_RECEIVERID = '$userId'OR $GAME_OTHERID = '$userId')
  ORDER BY $GAME_ID LIMIT 1"

本质上,我将$userId作为参数传递,并获得具有最小$GAME_ID值的行,对于表中具有约30 000个匹配行的用户,它将在不到100毫秒的时间内返回结果。但是,此后,我添加了新用户,这些用户具有<100个匹配的行,查询对于他们来说非常缓慢,每次大约需要20-30秒。

我很困惑,为什么在应该返回少量行的情况下查询如此慢,而在返回大量行的情况下却变得如此快,特别是因为我有ORDER BY

我已经阅读了有关参数嗅探的信息,但据我所知,这是SQL服务器的事,我正在使用MySQL

编辑

这里是SHOW CREATE语句:

[CREATE TABLE games( IDint(11) NOT NULL AUTO_INCREMENT, SenderIDint(11) NOT NULL, ReceiverIDint(11) NOT NULL, OtherIDint(11) NOT NULL, Timestamptimestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (ID ) ) ENGINE=MyISAM AUTO_INCREMENT=17275279 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

这里是EXPLAIN的输出

+----+-------------+-------+------+---------------+------+---------+-----+------+-------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | extra | +----+-------------+-------+------+---------------+------+---------+-----+------+-------+ | 1 | SIMPLE | games | NULL | index | NULL | PRIMARY | 4 | NULL | 1 | +----+-------------+-------+------+---------------+------+---------+-----+------+-------+

id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE games NULL index NULL PRIMARY 4 NULL 1 19.00 Using where

我尝试了准备好的语句,但仍然得到相同的结果。

对不起,格式化不好,我仍然对此不满意。

php mysql sql query-performance
2个回答
2
投票

EXPLAIN SELECT * FROM $TABLE_GAMES WHERE ($GAME_RECEIVERID = '$userId'OR $GAME_OTHERID = '$userId') ORDER BY $GAME_ID LIMIT 1"

EXPLAIN将提供有关带有执行计划的选择查询的信息。这是识别查询速度缓慢的好工具。根据获得的信息,您可以为Indexes子句中使用的列创建WHERE

CREATE INDEX index_name ON table_name (column_list)

这肯定会提高查​​询的性能。


0
投票
[$GAME_RECEIVERID$GAME_OTHERID不是索引的一部分时,就会出现该行为,由于顺序,促使MySQL使用$GAME_ID上的索引。但是,由于较新的玩家没有玩过早期的游戏,因此实际上有数百万行不匹配,但是仍然必须进行检查。

不幸的是,随着数据库的增长,即使对于老用户,这也将变得更加糟糕。理想情况下,您将在$GAME_RECEIVERID$GAME_OTHERID上添加索引-类似于:

ALTER TABLE games ADD INDEX receiver (ReceiverID), ADD INDEX other (OtherID)

PS:更改1700万行的表将花费一些时间,因此请确保在维护时段或在生产中使用的类似时段执行此操作。

© www.soinside.com 2019 - 2024. All rights reserved.