Tại sao đếm (*) chậm, khi giải thích biết câu trả lời?


14

Truy vấn này: select count(*) from planner_eventmất một thời gian rất dài để chạy - rất lâu, tôi đã từ bỏ và giết nó trước khi nó kết thúc. Tuy nhiên, khi tôi chạy explain select count(*) from planner_event, tôi có thể thấy một cột trong đầu ra với số lượng hàng (14m).

Làm thế nào giải thích có thể có được số lượng hàng ngay lập tức, nhưng đếm (*) mất nhiều thời gian để chạy?


COUNT (*) không có nguyên nhân WHERE sẽ gây ra quét bảng trên công cụ InnoDB .. MyISAM có thể phân phối số đếm trực tiếp vì COUNT được lưu trong tệp tiêu đề de khỏi bảng.
Raymond Nijland

Câu trả lời:


16

Giải thích là sử dụng số liệu thống kê được thu thập trước đó (được sử dụng bởi trình tối ưu hóa truy vấn). Thực hiện select count(*)đọc MỌI khối dữ liệu.

Đây là một cách rẻ tiền để có được số lượng hàng ước tính:

select TABLE_ROWS FROM INFORMATION_SCHEMA.TABLES where TABLE_NAME='planner_event';

Ngay cả khi bạn đã làm select count(id), nó vẫn có thể mất một thời gian rất dài, trừ khi bạn có một chỉ số phụ trên id(cũng giả sử idlà một KHÓA CHÍNH). Vì tất cả dữ liệu (bao gồm Dữ liệu Hàng) được lưu trữ trong các chỉ mục B-Tree, nên việc thực hiện a select count(PK_COLUMN)vẫn là một lượng IO đáng kể (cần phải đọc tất cả các trang dữ liệu). Nếu bạn có một chỉ mục phụ trên trường PK, nó sẽ có thể thực hiện ít IO hơn để thực hiện đếm.


I_S.TABLES mang đến cho bạn cùng một ước tính rằng EXPLAINmang đến cho bạn.
Rick James

Truy vấn bị thiếu AND TABLE_SCHEMA='my_database', nếu không, bạn sẽ nhận lại nhiều kết quả nếu bạn có một bảng có cùng tên trong cơ sở dữ liệu khác.
cz

3

Giải thích lấy số từ một số "thống kê" được sử dụng để ước tính mọi thứ cho Trình tối ưu hóa. Con số đó có thể không chính xác - đôi khi tôi thấy nó nhiều hơn hệ số 2 (cao hơn hoặc thấp hơn) so với giá trị chính xác.

Việc thực hiện COUNT(*)trên bảng InnoDB phải quét bảng để tránh ghi lại các bản ghi đang bận bị chèn / xóa bởi các kết nối khác nhưng chưa được "cam kết". Trên thực tế, nó là đủ tốt để thực hiện quét toàn bộ trên một số chỉ mục, không nhất thiết là toàn bộ bảng (có chứa PRIMARY KEY).

Bạn có bao nhiêu RAM? Giá trị của là innodb_buffer_pool_sizegì? Nó có thể hữu ích nếu đó là khoảng 70% RAM.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.