简体   繁体   English

使用带限制的 order by 时避免 mysql 中的全表扫描

[英]Avoid full table scan in mysql while using order by with limit

I m writing a query:我正在写一个查询:

select * from table_name order by id limit 21

Until i use the limit is lesser or equal to 20 the rows getting scanned is equal to the exact fetching rows (for example if the limit is 10, than the scanned rows also 10 only).在我使用限制小于或等于 20 之前,扫描的行等于确切的获取行(例如,如果限制为 10,则扫描的行也只有 10)。 If the limit exceeds 20 the table getting scanned fully.如果限制超过 20,则表将被完全扫描。

The only one index created for the primary key id only.仅为主键 id 创建的唯一一个索引。 Can anybody tell the reason for the full table scan in this case?在这种情况下,任何人都可以说出全表扫描的原因吗?


My table has 1099 rows.我的表有 1099 行。

Explain Result:
---------------------------------------------------------------------------
id|selecttype|table |type|possiblekeys|keys|key_len|ref |rows|  Extra       
---------------------------------------------------------------------------
1 | SIMPLE   |tablen|ALL |  null      |null|null   |null|1099|Usingfilesort 
---------------------------------------------------------------------------

In general case, to return rows for a LIMIT M, N MySQL will have to scan M+N rows of the result without LIMIT , and skip the first M-1 of them, hence full table scan.在一般情况下,要返回LIMIT M, N MySQL 将不得不扫描 M+N 行没有LIMIT的结果,并跳过其中的前 M-1 行,因此是全表扫描。

The first 20 rows in your case seem to fit into a single page, and since you order by the primary key, MySQL probably understands that it won't need to make full table scan.您的案例中的前 20 行似乎适合单个页面,并且由于您按主键排序,MySQL 可能明白它不需要进行全表扫描。

Another thing one should know, MySQL usually does not use any indexes for queries like SELECT * FROM T ORDER BY something , indexes are usually used when there is a condition, or if all the data can be fetched from the index directly (covering indexes).另一件应该知道的事情,MySQL 通常不使用任何索引进行查询,例如SELECT * FROM T ORDER BY something ,索引通常在有条件时使用,或者如果所有数据都可以直接从索引中获取(覆盖索引) .

When your primary key id gets incremented by one, you should be able to do the following query using a WHERE clause to get the data based on id instead of doing a full table scan with LIMIT .当您的主键id增加 1 时,您应该能够使用WHERE子句执行以下查询,以基于id获取数据,而不是使用LIMIT进行全表扫描。

SELECT * FROM table_name WHERE id BETWEEN 0 AND 21 ORDER BY id

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM