限制查询不能生效
Limit query can not be effective
我有一个关于 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;
即使使用limit查询也需要将近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被改变限制“"query,LIMIT 1,11"”,它需要几秒钟(像1或2秒)。
这些SQL的区别在LIMIT 4434950,11
和LIMIT 1,11
之间。
这个问题有办法解决吗?
了解两个极限的区别:
"LIMIT 1,11"
: 表示您只获取从 11 偏移量开始的 1 条记录。
"LIMIT 4434950,11"
:表示您正在从 11 偏移量开始获取 4434950 条记录。在这个查询中 table 扫描了数千行以获得 4434950 条记录然后它停止了,这肯定会花费更多的时间和资源,因为结果集也有很多行。
较高的偏移量会减慢查询速度是正常的,因为查询需要计算第一个 OFFSET + LIMIT 记录(并且只取其中的 LIMIT 个)。此值越高,查询运行的时间越长。
查询不能直接转到 OFFSET,因为首先,记录的长度可能不同,其次,删除的记录可能存在间隙。它需要检查和计算途中的每条记录。
加快查询速度的一些技巧:
MySQL 不能直接转到第 10000 条记录(或您建议的第 80000 个字节),因为它不能假设它是 packed/ordered 那样(或者它具有 1 到 10000 之间的连续值).尽管实际上可能是这样,MySQL 不能假设没有 holes/gaps/deleted 个 ID。
所以,
SELECT * FROM large ORDER BY id LIMIT 10000, 30
会很慢(呃),
SELECT * FROM large WHERE id > 10000 ORDER BY id LIMIT 30
会很快(呃),并且 return 会得到相同的结果,前提是没有丢失 ID(即间隙)。
Very good explanation here
我有一个关于 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;
即使使用limit查询也需要将近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被改变限制“"query,LIMIT 1,11"”,它需要几秒钟(像1或2秒)。
这些SQL的区别在LIMIT 4434950,11
和LIMIT 1,11
之间。
这个问题有办法解决吗?
了解两个极限的区别:
"LIMIT 1,11"
: 表示您只获取从 11 偏移量开始的 1 条记录。
"LIMIT 4434950,11"
:表示您正在从 11 偏移量开始获取 4434950 条记录。在这个查询中 table 扫描了数千行以获得 4434950 条记录然后它停止了,这肯定会花费更多的时间和资源,因为结果集也有很多行。
较高的偏移量会减慢查询速度是正常的,因为查询需要计算第一个 OFFSET + LIMIT 记录(并且只取其中的 LIMIT 个)。此值越高,查询运行的时间越长。
查询不能直接转到 OFFSET,因为首先,记录的长度可能不同,其次,删除的记录可能存在间隙。它需要检查和计算途中的每条记录。
加快查询速度的一些技巧:
MySQL 不能直接转到第 10000 条记录(或您建议的第 80000 个字节),因为它不能假设它是 packed/ordered 那样(或者它具有 1 到 10000 之间的连续值).尽管实际上可能是这样,MySQL 不能假设没有 holes/gaps/deleted 个 ID。
所以,
SELECT * FROM large ORDER BY id LIMIT 10000, 30
会很慢(呃),
SELECT * FROM large WHERE id > 10000 ORDER BY id LIMIT 30
会很快(呃),并且 return 会得到相同的结果,前提是没有丢失 ID(即间隙)。
Very good explanation here