PRIMARY KEY의 첫 번째 부분으로 DATETIME (또는 날짜)을 INDEXING하는 데 문제가 있습니다.
나는 MySQL 5.5를 사용한다
여기 내 두 테이블이 있습니다.
-- 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
나는 정확히 같은 데이터로 두 테이블을 채 웁니다 (10,000 근처)
그러나:
- 통계표는 dateDim에 DATETIME을 사용합니다.
- stats_todays는 dateDim에 대해 TO_DAYS ()와 함께 INTEGER를 사용하지 않습니다.
내 질문은 : 인덱스의 첫 부분이 날짜 시간 일 때 MySQL이 왜 기본 키를 사용하지 않는 이유는 무엇입니까 ??? 동일한 데이터를 사용하지만 INTEGER 및 TO_DAYS (dateDim)와 동일한 요청이 통합되어 있기 때문에 매우 이상합니다 ....
통계 테이블 및 날짜 시간을 사용한 예 :
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
다른 테이블 stats_todays에 대한 동일한 요청 (INTEGER 및 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
전체 게시물을 읽으면 요청이 INTEGER dateDim 필드와 정확히 동일한 카디널리티로 작동하므로 카디널리티 문제가 아님을 이해합니다 ....
고급 세부 정보는 다음과 같습니다.
SELECT COUNT( DISTINCT dateDim )
FROM stats_todays
UNION ALL
SELECT COUNT( DISTINCT dateDim )
FROM stats;
Result:
COUNT(DISTINCT dateDim)
2192
2192
다음은 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
SELECTDim, COUNT (*) 통계에서 GROUP BY dateDim WITH ROLLUP
- 2192 개의 서로 다른 날짜가 있고 재분할이 매끄럽다 고 알려줍니다 (날짜별로 약 3000-4000 행)
- 테이블에 8 831 990 개의 행이 있습니다
- 다른 테이블과 동일
- COVERING INDEX (모든 PK 열에 의해 * 대체) => 아무것도 변경되지 않았습니다.
- 나는 force | use index => 아무것도 변경하지 않았다.
- datetime 대신 date 필드와 동일
- 기본 키 대신 INDEX 또는 UNIQUE와 동일
그리고 당신이 달리면
—
ypercubeᵀᴹ
WHERE dateDim = DATE('2014-04-03 00:00:00')
?
date
대신에 사용하면 같은 일이 발생합니까datetime
?