MySQL에서이 테이블에 대해 어떤 종류의 PK를 선택해야하는지 궁금합니다. 거의 모든 SELECT 연산에는 DATETIME (날짜 범위, 특정 날짜 등)이 포함됩니다.DATETIME col이 거의 모든 SELECT 작업에 사용되는 테이블의 기본 키
모범 사례가 있습니까?
MySQL에서이 테이블에 대해 어떤 종류의 PK를 선택해야하는지 궁금합니다. 거의 모든 SELECT 연산에는 DATETIME (날짜 범위, 특정 날짜 등)이 포함됩니다.DATETIME col이 거의 모든 SELECT 작업에 사용되는 테이블의 기본 키
모범 사례가 있습니까?
DATETIME이 (가) 귀하의 PK가되지는 않을 것이지만 해당 열에 대해서는 반드시 create an index이어야합니다.
예, 해당'col'에 INDEX를 만들었습니다. –
안전 측면을 위해 자동 번호를 선택하십시오. 동일한 날짜 시간을 가진 두 개 이상의 행을 가질 수 있습니다.
특히 innodb를 사용하고 클러스터 된 기본 키 인덱스를 활용하여 최대 읽기 성능을 얻으려면 복합 기본 키의 일부를 형성하는 데 날짜를 사용하는 것이 좋습니다. 주의하는 것이
http://dev.mysql.com/doc/refman/5.0/en/innodb-index-types.html
http://www.xaprb.com/blog/2006/07/04/how-to-exploit-mysql-index-optimizations/
MySQL의 스크립트
것들 :
INNO을
는 다음에 봐 db는 auto_increment 복합 기본 키를 지원하지 않으므로 시퀀스 테이블을 사용합니다.기본 키의 auto_increment 부분은 고유성을 보장하는 데 도움이됩니다. 키의 바깥 부분은 중요한 부분 즉 날짜입니다. 여기
전체 스크립트를 http://pastie.org/1475625 또는 계속 읽고 ...
drop table if exists foo_seq;
create table foo_seq
(
next_val int unsigned not null default 0
)
engine = innodb;
insert into foo_seq values (0);
drop table if exists foo;
create table foo
(
foo_date datetime not null,
foo_id int unsigned not null, -- auto inc field which just guarantees uniqueness
primary key (foo_date, foo_id) -- clustered composite PK (innodb only)
)
engine=innodb;
delimiter #
create trigger foo_before_ins_trig before insert on foo
for each row
begin
declare v_id int unsigned default 0;
select next_val+1 into v_id from foo_seq;
set new.foo_id = v_id;
update foo_seq set next_val = v_id;
end#
delimiter ;
통계 :
select count(*) as counter from foo; -- count(*) under innodb always slow
+---------+
| counter |
+---------+
| 2000000 |
+---------+
select min(foo_date) as min_foo_date from foo;
+---------------------+
| min_foo_date |
+---------------------+
| 1782-11-21 16:32:00 |
+---------------------+
1 row in set (0.00 sec)
select max(foo_date) as max_foo_date from foo;
+---------------------+
| max_foo_date |
+---------------------+
| 2011-01-18 23:06:04 |
+---------------------+
1 row in set (0.00 sec)
select count(*) as counter from foo where foo_date between
'2009-01-01 00:00:00' and '2011-01-01 00:00:00';
+---------+
| counter |
+---------+
| 17520 |
+---------+
1 row in set (0.01 sec)
select * from foo where foo_date between
'2009-01-01 00:00:00' and '2011-01-01 00:00:00' order by 1 desc limit 10;
+---------------------+--------+
| foo_date | foo_id |
+---------------------+--------+
| 2010-12-31 23:06:04 | 433 |
| 2010-12-31 22:06:04 | 434 |
| 2010-12-31 21:06:04 | 435 |
| 2010-12-31 20:06:04 | 436 |
| 2010-12-31 19:06:04 | 437 |
| 2010-12-31 18:06:04 | 438 |
| 2010-12-31 17:06:04 | 439 |
| 2010-12-31 16:06:04 | 440 |
| 2010-12-31 15:06:04 | 441 |
| 2010-12-31 14:06:04 | 442 |
+---------------------+--------+
10 rows in set (0.00 sec)
explain
select * from foo where foo_date between
'2009-01-01 00:00:00' and '2011-01-01 00:00:00' order by 1 desc limit 10;
+----+-------------+-------+-------+---------------+---------+---------+------+-------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref |rows | Extra |
+----+-------------+-------+-------+---------------+---------+---------+------+-------+--------------------------+
| 1 | SIMPLE | foo | range | PRIMARY | PRIMARY | 8 | NULL |35308 | Using where; Using index |
+----+-------------+-------+-------+---------------+---------+---------+------+-------+--------------------------+
1 row in set (0.00 sec)
예쁜 확대됨가 200 만 개 행이 고려 ...
희망이 있습니다.
클러스터 된 인덱스를 기본 키로 사용하는 데 따른 제한 사항을 관리하므로 좋은 솔루션입니다. 클러스터 된 인덱스는 범위 쿼리에 유용합니다. –
MyISAM 또는 InnoDB? 기본 키는 선택과 어떤 관련이 있습니까? 아니면 클러스터 된 인덱스를 의미합니까? –
테이블에서 어떤 열이 고유합니까? 현명한 키 선택은 데이터와 비즈니스 규칙에 대한 분석과 이해를 기반으로해야합니다. – sqlvogel