一个表,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개 행을 반환하고 테이블을 추가한다는 의미입니다. 큰 필드가 포함되어 데이터베이스 쿼리의 I/O 시간이 필연적으로 늘어납니다.
쿼리 최적화를 위해서는 @Xing Aiming의
SELECT를 참조하세요. id,title,content FROM items WHERE id IN (SELECT id FROM items ORDER BY last_update_timelimit 10000, 10)
또 다른 최적화 방법이 있습니다. 매번 마지막 last_update_time 값을 기록할 수 있습니다. 그런 다음 쿼리는 다음과 같이 작성할 수 있습니다.
SELECT * FROM items WHERE last_update_time > "마지막으로 기록된 값" order by last_update_timelimit 0,10;
이 두 가지 방법을 구현하여 어느 것이 더 효율적인지 확인하는 것이 도움이 되기를 바랍니다. .