限制查询无效

时间:2017-04-11 05:59:10

标签: mysql limit explain

我对Mysql查询有疑问。

我的查询速度很慢。这是其中之一:

SELECT  
    xxx_accounts.id 
     , xxx_accounts.name 
     , xxx_accounts.account_name 
     , xxx_accounts.address_postalcode 
     , xxx_accounts.address_city 
     , xxx_accounts.address_state  
     , xxx_accounts.date_modified 
     , xxx_accounts.assigned_user_id   
FROM 
    xxx_accounts  
WHERE
    xxx_accounts.deleted = 0 
ORDER BY 
    xxx_accounts.date_entered DESC 
LIMIT 4434950, 11;

即使使用限制查询也需要近2分钟。

解释在这里:

+----+-------------+--------------+------+--------------------------------------------------------------------------------+-------------------------+---------+-------+---------+-------------+                     
| id | select_type | table        | type | possible_keys                                                                  | key                     | key_len | ref   | rows    | Extra       |
+----+-------------+--------------+------+--------------------------------------------------------------------------------+-------------------------+---------+-------+---------+-------------+
|  1 | SIMPLE      | xxx_accounts | ref  | idx_deleted_datemodified,idx_deleted_addresspostalcode,idx_deleted_dateentered | idx_deleted_dateentered | 2       | const | 1861322 | Using where |
+----+-------------+--------------+------+--------------------------------------------------------------------------------+-------------------------+---------+-------+---------+-------------+

这个解释说行是总数。

然而,这个SQL改变了限制""查询,LIMIT 1,11"",它需要几秒钟(如1或2秒)。

这些SQL的差异在LIMIT 4434950,11LIMIT 1,11之间。

这个问题能以某种方式解决吗?

1 个答案:

答案 0 :(得分:2)

了解两个限制之间的区别:

"LIMIT 1,11":表示从11偏移开始只提取1条记录。

"LIMIT 4434950,11":表示从11偏移量开始提取4434950条记录。在此查询表中扫描数千行以获取4434950条记录,然后停止,肯定会花费更多时间和资源,因为结果集也必须有很多行。

正常情况下,较高的偏移会减慢查询速度,因为查询需要计算第一个OFFSET + LIMIT记录(并且仅采用它们的LIMIT)。该值越高,查询运行的时间越长。

查询无法直接进入OFFSET,因为首先,记录的长度可能不同,其次,删除的记录可能存在间隙。它需要检查并统计每条记录。

快速进行此查询的一些技巧:

MySQL不能直接转到第10000条记录(或建议的第80000字节),因为它不能假设它是这样打包/排序的(或者它具有1到10000的连续值)。虽然实际上可能是这种方式,但MySQL不能假设没有漏洞/间隙/删除的ID。

所以,

SELECT * FROM large ORDER BY id LIMIT 10000, 30 

会很慢(呃),

SELECT * FROM large WHERE id >  10000 ORDER BY id LIMIT 30 

会很快(呃),如果没有丢失的ID(即间隙),它会返回相同的结果。

Very good explanation here