一个表,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개 행을 반환하고 테이블을 추가한다는 의미입니다. 큰 필드가 포함되어 데이터베이스 쿼리의 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;
이 두 가지 방법을 구현하여 어느 것이 더 효율적인지 확인하는 것이 도움이 되기를 바랍니다. .