哪个更快:SELECT DISTINCT 或 WHERE foo != 0?

Which is faster: SELECT DISTINCT or WHERE foo != 0?

id | foo | bar
--------------
0  | 0   | ...
1  | 1   | ...
2  | 2   | ...
3  | 0   | ...
4  | 2   | ...

我需要所有唯一的 foo 值,但不是经常出现的“0”。

哪个更快?

SELECT foo FROM `table` WHERE foo != 0

SELECT DISTINCT foo FROM `table`

最后一个将保留 0,但在 PHP 中被删除。

在我的服务器上,两者都足够快,但理论上这两个选项之一可能更快 :)

SELECT DISTINCT foo FROM `table`

因为没有Where条件

根据所给出的条件,distinct 会很昂贵,因为它会在消除重复记录之前对从主内存中获取的块中的所有记录进行排序,而 selectwhere 条件是对块中的每条记录只迭代一次以过滤掉记录。

最著名的排序算法也在 O(nlogn) 内完成,而迭代记录检查发生在 O(n) 时间内。

因此,第一个查询更快此处

希望它能解答您的问题。

在我的大多数情况下,SELECT foo FROM table WHERE foo != 0更快。

但在您的情况下,可以更快:

SELECT foo FROM `table` WHERE foo > 0

根据您显示的数据,您没有负值,因此您不需要检查任何负值。 (正如所指出的 here - MySQL docs - 滚动到评论部分)

来自MySQL Distinct docs

In most cases, a DISTINCT clause can be considered as a special case of GROUP BY

因此,如果性能是一个问题并且您真的不需要它,请不要使用它。

这是一个包含 130,000 行的索引数据集。稀疏列的值在 0-100000 范围内。密集列的值在 0-100 范围内。

SELECT * FROM my_table;
+----+--------+-------+
| id | sparse | dense |
+----+--------+-------+
|  1 |      0 |     0 |
|  2 |  52863 |    87 |
|  3 |  76503 |    21 |
|  4 |  77783 |    25 |
|  6 |  89359 |    73 |
|  7 |  97772 |    69 |
|  8 |  53429 |    59 |
|  9 |  35206 |    99 |
| 13 |  88062 |    44 |
| 14 |  56312 |    49 |
...

SELECT * FROM my_table WHERE sparse <> 0;
130941 rows in set (0.09 sec)

SELECT * FROM my_table WHERE dense <> 0;
130289 rows in set (0.09 sec)

SELECT DISTINCT sparse FROM my_table;
72844 rows in set (0.27 sec)

SELECT DISTINCT dense FROM my_table;
101 rows in set (0.00 sec)

如您所见,DISTINCT 是否更快在很大程度上取决于数据的密度。

显然,在这种情况下,两个查询彼此非常不同!