我有以下查询:
SELECT `masters_tp`.*, `masters_cp`.`cp` as cp, `masters_cp`.`punti` as punti
FROM (`masters_tp`)
LEFT JOIN `masters_cp` ON `masters_cp`.`nickname` = `masters_tp`.`nickname`
WHERE `masters_tp`.`stake` = 'report_A'
AND `masters_cp`.`stake` = 'report_A'
ORDER BY `masters_tp`.`tp` DESC, `masters_cp`.`punti` DESC
LIMIT 400;
Run Code Online (Sandbox Code Playgroud)
此查询是否存在可能影响服务器内存的问题?
这是EXPLAIN的输出
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+------+---------------+------+---------+------+-------+----------------------------------------------+
| 1 | SIMPLE | masters_cp | ALL | NULL | NULL | NULL | NULL | 8943 | Using where; Using temporary; Using filesort |
| 1 | SIMPLE | masters_tp | ALL | NULL | NULL | NULL | NULL | 12693 | Using where |
Run Code Online (Sandbox Code Playgroud)
运行带有EXPLAIN前缀的相同查询并将输出添加到您的问题中 - 这将显示您正在使用的索引和正在分析的行数.
您可以从解释中看到没有使用索引,并且必须查看数千行才能获得结果.尝试在用于执行连接的列上添加索引,例如昵称和桩号:
ALTER TABLE masters_tp ADD INDEX(nickname),ADD INDEX(stake);
ALTER TABLE masters_cp ADD INDEX(nickname),ADD INDEX(stake);
Run Code Online (Sandbox Code Playgroud)
(我假设列可能有重复的值,如果没有,使用UNIQUE而不是INDEX).有关更多信息,请参阅MySQL手册.
实际上没有理由在left join这里做.您正在使用过滤器来消除连接的任何左边.试试这个:
SELECT
`masters_tp`.*,
`masters_cp`.`cp` as cp,
`masters_cp`.`punti` as punti
FROM
`masters_tp`
INNER JOIN `masters_cp` ON
`masters_tp`.`stake` = `masters_cp`.stake`
and `masters_tp`.`nickname` = `masters_cp`.`nickname`
WHERE
`masters_tp`.`stake` = 'report_A'
ORDER BY
`masters_tp`.`tp` DESC,
`masters_cp`.`punti` DESC
LIMIT 400;
Run Code Online (Sandbox Code Playgroud)
inner joins往往比left joins 快.查询可以使用谓词(也就是where子句)限制必须连接的行数.这意味着,数据库处理,潜在的,一个很大的行数更少,这显然加快东西.
此外,请确保您具有非聚集索引stake和nickname(按此顺序).
| 归档时间: |
|
| 查看次数: |
105 次 |
| 最近记录: |