一个表,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)
请大神请教,是什么问题?该怎么优化?
ringa_lee2017-04-17 16:02:16
コンテンツがない場合、クエリは idx_last_update_time になると思います。このインデックスには id フィールドと name フィールドが含まれているため、必要なデータはインデックス経由でのみ取得できるため、非常に高速です。
コンテンツがある場合、ステートメントの制限が 10000 であり、インデックスからコンテンツ フィールドのコンテンツを取得できないため、フル テーブル スキャンが使用されます。
id が主キーであると仮定して、データベース実行プランでインデックスをより完全に使用できるように SQL ステートメントを書き直すことをお勧めします。
巴扎黑2017-04-17 16:02:16
コンテンツにはテキストやコードなどが含まれており、平均長は 20k 以上です。
これにより、フルテキスト インデックス (FUNLLTEXT INDEX) が確立されます。単純なインデックスは、このような非常に長いテキスト フィールドには適していません。
PHP中文网2017-04-17 16:02:16
これは主にページングクエリメソッドに関連していると思います。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 つの方法を実装して、どちらがより効率的であるかを確認してください。お役に立てれば幸いです。 。