Tôi gặp vấn đề với việc CHỈ ĐỊNH MỘT ĐẠI SỐ (hoặc thậm chí là một ngày) là phần đầu tiên của KHÓA CHÍNH.
Tôi sử dụng MySQL 5.5
Đây là hai bảng của tôi:
-- This is my standard table with dateDim as a dateTime
CREATE TABLE `stats` (
`dateDim` datetime NOT NULL,
`accountDim` mediumint(8) unsigned NOT NULL,
`execCodeDim` smallint(5) unsigned NOT NULL,
`operationTypeDim` tinyint(3) unsigned NOT NULL,
`junkDim` tinyint(3) unsigned NOT NULL,
`ipCountryDim` smallint(5) unsigned NOT NULL,
`count` int(10) unsigned NOT NULL,
`amount` bigint(20) NOT NULL,
PRIMARY KEY (`dateDim`,`accountDim`,`execCodeDim`,`operationTypeDim`,`junkDim`,`ipCountryDim`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
-- Here is a copy with datDim as an integer
CREATE TABLE `stats_todays` (
`dateDim` int(11) unsigned NOT NULL,
`accountDim` mediumint(8) unsigned NOT NULL,
`execCodeDim` smallint(5) unsigned NOT NULL,
`operationTypeDim` tinyint(3) unsigned NOT NULL,
`junkDim` tinyint(3) unsigned NOT NULL,
`ipCountryDim` smallint(5) unsigned NOT NULL,
`count` int(10) unsigned NOT NULL,
`amount` bigint(20) NOT NULL,
PRIMARY KEY (`dateDim`,`accountDim`,`execCodeDim`,`operationTypeDim`,`junkDim`,`ipCountryDim`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
Tôi điền vào cả hai bảng với cùng một dữ liệu (gần 10 000 000)
Nhưng:
- bảng thống kê sử dụng một dữ liệu dữ liệu cho dateDim
- stats_todays sử dụng un INTEGER với TO_DAYS () cho dateDim
Câu hỏi của tôi là: tại sao MySQL không sử dụng KHÓA CHÍNH khi phần đầu tiên của chỉ mục là datetime ??? Điều này rất lạ vì Với cùng một dữ liệu nhưng được hợp nhất với một INTEGER và TO_DAYS (dateDim) cùng một yêu cầu đá ....
Ví dụ với bảng thống kê (và datetime):
SELECT *
FROM `stats`
WHERE
dateDim = '2014-04-03 00:00:00'
AND accountDim = 4
AND execCodeDim = 9
AND operationTypeDim = 1
AND junkDim = 5
AND ipCountryDim = 3
=> 1 result (4.5sec)
Explain:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE stats ALL NULL NULL NULL NULL 8832329 Using where
Yêu cầu tương tự trên bảng stats_todays khác (Với INTEGER và TO_DAYS ())
EXPLAIN SELECT *
FROM `stats_todays`
WHERE
dateDim = TO_DAYS('2014-04-03 00:00:00')
AND accountDim = 4
AND execCodeDim = 9
AND operationTypeDim = 1
AND junkDim = 5
AND ipCountryDim = 3
=> Result 1 row (0.0003 sec)
Explain:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE stats_todays const PRIMARY PRIMARY 13 const,const,const,const,const,const 1
Nếu bạn đọc toàn bộ bài đăng, bạn hiểu rằng đó không phải là vấn đề về số lượng thẻ thấp vì yêu cầu hoạt động với cùng một số lượng chính xác với trường INTEGER dateDim ....
Dưới đây là một số chi tiết nâng cao:
SELECT COUNT( DISTINCT dateDim )
FROM stats_todays
UNION ALL
SELECT COUNT( DISTINCT dateDim )
FROM stats;
Result:
COUNT(DISTINCT dateDim)
2192
2192
Dưới đây là mô tả INDEX:
SHOW INDEXES FROM `stats`
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
stats 0 PRIMARY 1 dateDim A 6921 NULL NULL BTREE
stats 0 PRIMARY 2 accountDim A 883232 NULL NULL BTREE
stats 0 PRIMARY 3 execCodeDim A 8832329 NULL NULL BTREE
stats 0 PRIMARY 4 operationTypeDim A 8832329 NULL NULL BTREE
stats 0 PRIMARY 5 junkDim A 8832329 NULL NULL BTREE
stats 0 PRIMARY 6 ipCountryDim A 8832329 NULL NULL BTREE
SHOW INDEXES FROM `stats_todays`
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
stats_todays 0 PRIMARY 1 dateDim A 7518 NULL NULL BTREE
stats_todays 0 PRIMARY 2 accountDim A 4022582 NULL NULL BTREE
stats_todays 0 PRIMARY 3 execCodeDim A 8045164 NULL NULL BTREE
stats_todays 0 PRIMARY 4 operationTypeDim A 8045164 NULL NULL BTREE
stats_todays 0 PRIMARY 5 junkDim A 8045164 NULL NULL BTREE
stats_todays 0 PRIMARY 6 ipCountryDim A 8045164 NULL NULL BTREE
CHỌN dateDim, COUNT (*) TỪ thống kê NHÓM THEO dateDim VỚI ROLLUP
- cho biết có 2192 ngày khác nhau và quá trình phân chia lại diễn ra suôn sẻ (khoảng 3000 - 4000 hàng theo ngày)
- có 8 831 990 hàng trong bảng
- Tương tự cho các bảng khác
- Tôi đã thử với COVERING INDEX (thay thế * bằng tất cả các cột PK) => không có gì thay đổi
- Tôi đã thử dùng lực | chỉ số => không có gì thay đổi
- Tương tự với trường ngày thay vì datetime
- Tương tự với INDEX hoặc UNIQUE thay vì khóa chính
WHERE dateDim = DATE('2014-04-03 00:00:00')
?
date
thay vìdatetime
?