Первичный ключ для таблицы, в которой столбец DATETIME используется почти для всех операций SELECT. - PullRequest
1 голос
/ 19 января 2011

Мне интересно, какой тип ПК я должен выбрать для этой таблицы в MySQL. Почти все операции SELECT будут включать DATETIME (диапазоны дат, конкретную дату и т. Д.).

Есть ли лучшая практика для этого?

Ответы [ 3 ]

4 голосов
/ 19 января 2011

Я бы не рекомендовал, чтобы DATETIME был вашим ПК, но вам непременно следует создать индекс для этого столбца.

1 голос
/ 19 января 2011

Вполне допустимо использовать даты для формирования части составного первичного ключа, особенно если вы используете 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 script

На заметку:

  • innodb не поддерживает составные первичные ключи 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)

Довольно производительно, учитывая, что есть 2 миллиона строк ...

Надеюсь, это поможет:)

0 голосов
/ 19 января 2011

Выберите автономный номер, чтобы быть в безопасности. Вы можете иметь две или более строки с одинаковыми датами и временем.

...