一个表,1.5w条数据,字段: id,name,content,last_update_time
id,自定义主键
name,varchar类型
content是longtext类型,
last_update_time为datetime类型,不为空
content当中是文本和代码等,平均长度在20k+。
case1:
select id, name from t order by last_update_time limit 10000, 10当content当中有大量的文本时,case1的效率极慢。
及时给 last_update_time 加上btree索引, 效率有提升,但是依然慢
把content一列删掉,效率很高。毫秒级别。
使用explain:
有content时结果:
mysql> explain select id, name, last_update_time from t order by last_update_time desc limit 11120, 11;
+----+-------------+-----------+-------+---------------+----------------------+---------+------+-------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+-------+---------------+----------------------+---------+------+-------+-------+
| 1 | SIMPLE | t | index | NULL | idx_last_update_time | 8 | NULL | 11131 | NULL |
+----+-------------+-----------+-------+---------------+----------------------+---------+------+-------+-------+
无content列的结果:
+----+-------------+----------------+------+---------------+------+---------+------+-------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------------+------+---------------+------+---------+------+-------+----------------+
| 1 | SIMPLE | t2 | ALL | NULL | NULL | NULL | NULL | 15544 | Using filesort |
+----+-------------+----------------+------+---------------+------+---------+------+-------+----------------+
1 row in set (0.00 sec)
请大神请教,是什么问题?该怎么优化?
コンテンツがない場合、クエリは idx_last_update_time になると思います。このインデックスには id フィールドと name フィールドが含まれているため、必要なデータはインデックス経由でのみ取得できるため、非常に高速です。
リーリーコンテンツがある場合、ステートメントの制限が 10000 であり、インデックスからコンテンツ フィールドのコンテンツを取得できないため、フル テーブル スキャンが使用されます。
id が主キーであると仮定して、データベース実行プランでインデックスをより完全に使用できるように SQL ステートメントを書き直すことをお勧めします。
これにより、フルテキスト インデックス (FUNLLTEXT INDEX) が確立されます。単純なインデックスは、このような非常に長いテキスト フィールドには適していません。
これは主にページングクエリメソッドに関連していると思います。Limit 10000,10 は、条件を満たす 10010 個のデータをスキャンし、最初の 10000 行を破棄し、最後の 10 行を返し、テーブルを追加することを意味します。
クエリの最適化については、@Xing Aiming の
SELECT id、title、content FROM items WHERE id IN (SELECT id FROM) を参照できます。 items ORDER BY last_update_time limit 10000, 10);
別の最適化方法があります。last_update_time の最後の値を毎回記録できます。次に、クエリは次のように記述できます:
SELECT * FROM items WHERE last_update_time > "最後に記録された値" order by last_update_time limit 0,10;
これら 2 つの方法を実装して、どちらがより効率的であるかを確認してください。お役に立てれば幸いです。 。