MySQL视图count速度优化
ringa_lee
ringa_lee 2017-04-17 16:20:04
0
5
907

背景:
程序列表页展示信息,需后台多表关联读取视图,视图内sql已优化(索引、语句),外层增加查询条件后速度基本一致。
VIEW:

CREATE VIEW a
AS
SELECT *
FROM b FORCE INDEX (`idx_b`)
JOIN a ON a.CId = b.Id
JOIN c ON c.CId = b.Id
LEFT JOIN s ON s.No = c.No
LEFT JOIN d ON d.CId = a.Id AND d.EId = c.Id
LEFT JOIN e FORCE INDEX (`idx_e`) ON e.CId = a.Id
WHERE b.isdeleted = 0

环境:
1).mysql 5.7.10 InnoDB引擎 2核4G
2).阿里云RDS 4核8G (貌似效果更差<分片性能会衰减>)
问题:
1.外层增加排序order by条件后,速度变慢,查看执行计划为将试图内数据转化为temp_table后再进行sort;
2.直接count视图的话更加缓慢,已达不能接受地步,列表分页肯定需展示总条数,抛除视图,直接使用sql也是很缓慢。
大神们指点指点怎样优化mysql多表关联的count

ringa_lee
ringa_lee

ringa_lee

모든 응답(5)
巴扎黑

귀하께서 작성하신 SQL 문을 바탕으로 몇 가지 제안을 드립니다.
1. 테이블 B는 강제 인덱스를 사용하여 테이블 항목 수가 많은 경우 인덱스 쿼리가 실행되지 않을 수 있습니다. 최적의 방법입니다. 일반적인 상황에서는 데이터베이스가 선택하도록 할 수 있습니다. 아니면 직접 확인하고, isdeleted = 0이라는 조건을 이용해 테이블 ​​b를 확인한 후 force index를 사용하면 성능이 더 좋은지 확인하고, 그렇지 않으면 force index를 제거하세요.
2. SQL 문 수를 계산하려면 테이블 a, b, c만 유지하세요. 다른 테이블은 왼쪽 조인이므로 통계 결과에 영향을 미치지 않습니다.
3. 이전 단계에서 기본 키 필드는 자세한 정보를 얻기 위해 PHP에서 반복됩니다. 일반적으로 페이지 수가 적기 때문에 기본 키를 통해 데이터를 여러 번 가져오는 것이 더 빠를 수 있습니다.

그리고 모두가 분석하기를 원한다면 SQL 실행 계획을 게시하는 것이 가장 좋습니다.

Ty80

모든 사람이 볼 수 있도록 SQL 문을 게시하세요.

Ty80

여러 번 쿼리한 후 합산하여 총 레코드 수를 가져옵니다. 어때요? ? (테스트되지 않았습니다....)

예를 들어 각 쿼리의 데이터 양은 8000개 레코드입니다

PHP 代码

으아아아
迷茫

결국 쿼리하게 되는 것은 테이블 b의 데이터입니다. 테이블 b를 카운트하면 왜 다른 테이블을 조인해야 합니까? 카운트는 전체 테이블 스캔이며 기본적으로 어디에 추가하지 않는 한 최적화 방법이 없습니다.

黄舟

처음에는 총 항목 수를 비동기식으로 로드하여 데이터와 페이지 번호가 먼저 나오도록 하는 것이 연구 개발이었습니다. 이런 식으로 의도적으로 번호를 확인하지 않는 한, 발생하지 않습니다.
나중에 위의 제안을 읽고 뷰를 변경하면 총 로드 수도 더 빨라질 것입니다.
또한 뷰를 사용할 때 외부 조건을 색인화할 수 있도록 필수 색인이 추가되었습니다.
당분간은 이 최적화가 허용됩니다.

최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿