mysql - 哪种 PDO SQL 查询在长期和大量数据中更快?

标签 mysql pdo query-optimization

从一个表中有超过 百万条记录,当我从中提取数据时,

我想检查请求的数据是否存在,那么哪条路径比另一条路径更有效更快

$Query = '
    SELECT n.id 
    FROM names n 
    INNER JOIN ages a ON n.id = a.aid 
    INNER JOIN regions r ON n.id = r.rid 
    WHERE id = :id
';

$stmt->prepare($Query);
$stmt->execute(['id' => $id]);
if ($stmt->rowCount() == 1) {
    $row = $stmt->fetch();
    ......................
} else {
    exit();
}

$EXISTS = 'SELECT EXISTS (
    SELECT n.fname, n.lname, a.age, r.region 
    FROM names n 
    INNER JOIN ages a ON n.id = a.aid 
    INNER JOIN regions r ON n.id = r.rid 
    WHERE id = :id
    LIMIT 1
)
';
$stmt->prepare($EXISTS);
$stmt->execute(['id' => $id]);
if ($stmt->fetchColumn() == 1) {
    $stmt->prepare($Query);
    $stmt->execute(['id' => $id]);
    $row = $stmt->fetch();
    ......................
} else {
    exit();
}

记住 idPRIMARY (INT)aid, ridINDEXED (INT)

最佳答案

您展示的这两种方法几乎可以肯定是等效的,在性能上几乎没有可衡量的差异。

SELECT n.id 
FROM names n 
INNER JOIN ages a ON n.id = a.aid 
INNER JOIN regions r ON n.id = r.rid 
WHERE id = :id

我假设 names.id 是该表的主键。主键查找非常快。

然后它将对其他两个表进行辅助键查找,这将是一个仅索引访问,因为没有对这些表的其他列的引用。

你应该学习如何使用 EXPLAIN 来分析 MySQL 的优化计划。每当您想提高 SQL 查询的性能时,您都应该练习这项技能。

参见 https://dev.mysql.com/doc/refman/5.7/en/using-explain.html

mysql> explain SELECT n.id 
    ->     FROM names n 
    ->     INNER JOIN ages a ON n.id = a.aid 
    ->     INNER JOIN regions r ON n.id = r.rid 
    ->     WHERE id = 1;

+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type  | possible_keys | key     | key_len | ref   | rows | filtered | Extra       |
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | n     | NULL       | const | PRIMARY       | PRIMARY | 4       | const |    1 |   100.00 | Using index |
|  1 | SIMPLE      | a     | NULL       | ref   | aid           | aid     | 5       | const |    1 |   100.00 | Using index |
|  1 | SIMPLE      | r     | NULL       | ref   | rid           | rid     | 5       | const |    1 |   100.00 | Using index |
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+

我们看到每个表访问都使用索引(我假设索引,虽然你没有在你的问题中提供你的 SHOW CREATE TABLE)。

比较第二个解决方案SELECT EXISTS(...)

mysql> explain SELECT EXISTS (
    ->     SELECT n.id 
    ->     FROM names n 
    ->     INNER JOIN ages a ON n.id = a.aid 
    ->     INNER JOIN regions r ON n.id = r.rid 
    ->     WHERE id = 1 
    ->     LIMIT 1);

+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+----------------+
| id | select_type | table | partitions | type  | possible_keys | key     | key_len | ref   | rows | filtered | Extra          |
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+----------------+
|  1 | PRIMARY     | NULL  | NULL       | NULL  | NULL          | NULL    | NULL    | NULL  | NULL |     NULL | No tables used |
|  2 | SUBQUERY    | n     | NULL       | const | PRIMARY       | PRIMARY | 4       | const |    1 |   100.00 | Using index    |
|  2 | SUBQUERY    | a     | NULL       | ref   | aid           | aid     | 5       | const |    1 |   100.00 | Using index    |
|  2 | SUBQUERY    | r     | NULL       | ref   | rid           | rid     | 5       | const |    1 |   100.00 | Using index    |
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+----------------+

子查询看起来与第一个查询优化计划相同;它仍然以相同的方式使用索引。但它被降级为子查询。可能差别不大,但又是一回事。

唯一的优点是 SELECT EXISTS... 查询保证只返回一行带有 true/false 值。第一个查询可能会返回包含零行、一行或多行的结果集,具体取决于查询中有多少行与 JOIN 匹配。区别不是性能差异(除非它返回的行太多以至于将结果集传输到客户端需要时间,或者使用大量内存来保存客户端中的结果集),而只是为了方便你编码的方式。

关于mysql - 哪种 PDO SQL 查询在长期和大量数据中更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47955316/

相关文章:

mysql - 在某些情况下语句之间缺少索引

MySQL查看问题

mysql - 找出 MySQL 索引的使用统计信息?

mysql - 使用 MySQL Distinct 显示列中的唯一值,其中某些值带有特殊字符

php - 连接 2 个表的 PDO Sql 查询返回一行

php - 使用 REPLACE 和 LIKE 更新 MySQL

php - MySQL:有索引和小文件排序更好还是没有索引和文件排序更好?

mysql - 在寻找饮料时找到最近的酒吧

php - 你如何决定你在你的配置文件和你的数据库中放置的内容

php - 未捕获的异常 'PDOException',消息为 'could not find driver'