CREATE TABLE 收藏表( `id` bigint(20) unsigned NOT NULL auto_increment COMMENT 'primary key', `uid` bigint(20) unsigned NOT NULL default 0 COMMENT 'uid',
`status` tinyint(3) unsigned NOT NULL default 0 COMMENT 'status', `book_id` bigint(20) unsigned NOT NULL default 0 COMMENT 'book Id', `create_time` int(11) unsigned not null default 0 COMMENT 'create time', PRIMARY KEY (`id`), UNIQUE KEY `uid_book_id` (`uid`, `book_id`),
KEY `uid_status` (`uid`, `status`) )ENGINED=Innodb Auto_increment=1 default charset=gbk COMMENT '用戶收藏信息';
最容易想到的第一種分頁語句是(這也是我們最容易想到的語句):
select distinct uid from 收藏表 order by uid desc limit 0, 10; select distinct uid from 收藏表 order by uid desc limit 11, 10;
再高級點語句,第二種($last_min_uid表示上一次讀到的最后一個uid):
select distinct uid from 收藏表 order by uid desc limit 10; select distinct uid from 收藏表 where uid < $last_min_uid order by uid desc limit 10;
最高級的方式
select uid from 收藏表 group by uid order by uid desc limit 10; select uid from 收藏表 group by uid having uid < $last_min_uid order by uid desc limit 10;
以上三種方式都可以實現分頁獲取到用戶ID列表,那么區別是什么?我現在就把每一種跟大家分析下。
第一種在業務場景中,會出現丟數據的情況。——這是比較嚴重的情況,不予采納。
具體的業務場景是這樣的:當你讀取第5頁的時候,前四頁的用戶id列表中,假如有一頁的用戶ID從庫中刪除掉,那么你這時讀到的第5頁(limit 51, 10),就是原來的第6頁,你會把1頁的用戶ID丟失掉。
第二種的第二條語句,通過explain分析,實際並沒有命中唯一索引,而只是命中了一般索引,數據查詢范圍在7百萬級別,故explain建議我們使用group by。——這個查詢會有嚴重的性能問題。
+----+--------------+---------------+-------+-------------------------------------------------------------+-------------+----------+-------+------------+------------------------------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------+---------------+-------+-------------------------------------------------------------+---------------------+---------+------+---------+---------------------------------------------------------------------+
| 1 | SIMPLE | ubook_room | range | uid_book_id | uid_status | 4 | NULL | 7066423 | Using where; Using index for group-by; Using temporary; Using filesort |
+----+--------------+---------------+-------+-------------------------------------------------------------+-------------+----------+-------+------------+------------------------------------------------------------------------+
第三種explain分析,數據查詢范圍在12萬級別(跟第二種相差一個數量級),查詢性能高。
+----+---------------+------------+-------+-----------------+-----------------+---------+----------+----------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+---------------+------------+-------+-----------------+-----------------+---------+----------+----------+-------------+
| 1 | SIMPLE | 收藏表 | index | NULL | uid_book_id | 12 | NULL | 121719 | Using index |
+----+---------------+------------+-------+-----------------+-----------------+---------+----------+----------+-------------+
