SELECT
*
FROM
`order`
WHERE user_id = 1
ORDER BY `create_at` DESC
LIMIT 12 OFFSET 15000
表中有20万+数据。现在这条语句查询需要20秒。 当LIMIT 12 OFFSET 12
或者 24,36等等前面的页速度都还不错,但是随着页数的增加,也就是OFFSET变化,越大越慢。
表id(主键,自增),user_id,create_at都增加了索引。
请问应该如何解决这个问题。
这里的where 条件只列了一个, 实际上可能还有更多的可能性。如果有更多的where又该如何?
orderby 目前肯定是针对已经有索引页的字段进行排序的,但是也有3个,时间字段。
谢谢。
//ddl
CREATE TABLE `foobar` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`identdify` bigint(20) DEFAULT '0',
`type` int(11) DEFAULT '0',
`status` int(11) DEFAULT '0',
`way` int(11) DEFAULT '0',
`api` int(11) DEFAULT '0',
`node` int(11) DEFAULT '0',
`apply_by` int(11) DEFAULT '0',
`apply_at` int(11) DEFAULT '0',
`create_by` int(11) DEFAULT '0',
`create_at` int(11) DEFAULT '0',
`confirm_by` int(11) DEFAULT '0',
`confirm_at` int(11) DEFAULT '0',
`check_by` int(11) DEFAULT '0',
`check_at` int(11) DEFAULT '0',
`money_1` decimal(20,2) DEFAULT '0.00',
`money_2` decimal(20,2) DEFAULT '0.00',
`money_3` decimal(20,2) DEFAULT '0.00',
`money_4` decimal(20,2) DEFAULT '0.00',
`money_5` decimal(20,2) DEFAULT '0.00',
`money_6` decimal(20,2) DEFAULT '0.00',
`money_7` decimal(20,2) DEFAULT '0.00',
`money_8` decimal(20,2) DEFAULT '0.00',
`api_identify` varchar(255) DEFAULT NULL,
`client_name` varchar(255) DEFAULT NULL,
`remark` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `type` (`type`),
KEY `status` (`status`),
KEY `way` (`way`),
KEY `node` (`node`),
KEY `apply_by` (`apply_by`),
KEY `apply_at` (`apply_at`),
KEY `create_by` (`create_by`),
KEY `create_at` (`create_at`),
KEY `confirm_by` (`confirm_by`),
KEY `create_at_2` (`create_at`)
) ENGINE=MyISAM AUTO_INCREMENT=251720 DEFAULT CHARSET=utf8
SELECT count(*) FROM `foobar`;
+----------+
| count(*) |
+----------+
| 251719 |
+----------+
1 row in set (0.00 sec)
SELECT
*
FROM
`foobar`
WHERE way = 1
ORDER BY create_at DESC
LIMIT 12 OFFSET 20000
// 耗时 25.890 秒
EXPLAIN
-> SELECT
-> *
-> FROM
-> `foobar`
-> WHERE way = 1
-> ORDER BY create_at DESC
-> LIMIT 12 OFFSET 20000 \G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: foobar
type: range
possible_keys: way
key: way
key_len: 5
ref: NULL
rows: 251028
Extra: Using index condition; Using filesort
1 row in set (0.00 sec)
SELECT
*
FROM
`foobar`
WHERE way = 1
AND api = 1
ORDER BY create_at DESC
LIMIT 12 OFFSET 20000
//耗时 24.585
> EXPLAIN
-> SELECT
-> *
-> FROM
-> `foobar`
-> WHERE way = 1
-> AND api = 1
-> ORDER BY create_at DESC
-> LIMIT 12 OFFSET 20000 \G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: foobar
type: range
possible_keys: way
key: way
key_len: 5
ref: NULL
rows: 251028
Extra: Using index condition; Using where; Using filesort
1 row in set (0.00 sec)
ERROR: No query specified
Post the table structure and explain
It seems that the way field of the poster’s table is almost always 1, and the api field is almost always 1. . . . .
You can try adding two joint indexes
ix_way_create_at (way,create_at)
ix_way_api_create_at (way, api, create_at)
Are you sure it’s not a hardware problem such as insufficient memory? I reproduced your query and it only takes 0.02 seconds for 1 million pieces of data.
You can try order by id because your create_at is actually calculated based on this time. If you still have problems after trying it, please post pictures and more detailed data for analysis.