MySQL 的 SELECT WHERE 如何进行整数比较?

How does MySQL's SELECT WHERE do integer comparisons?

假设我有一个 MySQL 查询,例如

SELECT `id` FROM `posts` WHERE `views` >= 100

MySQL 会怎么做?它是否 select 数据库中的每个值,检查查看次数是否大于 100,如果是,则将其添加到结果中?

如果这是对 Java 中的 HashMap 的查询,它将看起来像这样

Map<String, Integer> views = new HashMap<String, Integer>();
List<String> results = new ArrayList<String>();

for(String id : views.keys()){
    if(views.get(id) >= 100){
        results.add(id);
    }
}

return results;

但是如果 table 有数万或数十万行,那似乎不是很有效。 SELECT WHERE如何进行整数比较?如果它从数据库中获取每个值并根据 WHERE 条件对其进行检查,它是否会占用大量资源,是否应该在生产环境中使用?

给定一个没有索引的 table,扫描和测试每一行正是 MySQL 所做的。这就是索引对性能至关重要的原因。

使用索引 MySQL 将查看它并找到 100 所在的位置,然后从该点开始读取行。这适用于 <>BETWEEN 运算符等边界。

未编入索引的 table 应被视为随机数据列表,没有固有顺序。索引 table 按一列或多列排序,因此检索很容易。考虑在 phone 书中找到所有姓 "Thompson" 的人,而不是在满是写在纸片上的名字的盒子里。在一种情况下,您可以翻到正确的页面并从那里开始阅读,而在另一种情况下,您必须阅读框中的每个名字。

如果您想知道 MySQL 将如何处理您的查询,请执行以下操作:

EXPLAIN SELECT id FROM posts WHERE views >= 100

如果您看到 "table scan",这意味着它必须测试每一行并且应该添加一个索引。

当您在列 views 上没有索引时,这意味着引擎必须扫描所有数据页并对每一行进行比较。如果这是真的,那确实像你描述的那样。

现在有了索引,就可以用对数时间在B-tree中搜索了。引擎可以很容易地确定所有需要的数据页,因为索引是有序的,并且只加载那些数据页。现在有一些细微差别,比如如果您选择同一列,那么引擎不需要进行更多读取,或者如果您选择其他一些列,它必须为每一行执行聚簇索引查找。等等等等