Не используются ключи

MySQL/PostgreSQL/SQLite/Oracle/M$SQL/....

Модератор: terminus

Правила форума
Убедительная просьба юзать теги [code] при оформлении листингов.
Сообщения не оформленные должным образом имеют все шансы быть незамеченными.
Аватара пользователя
Alex Keda
стреляли...
Сообщения: 35428
Зарегистрирован: 2004-10-18 14:25:19
Откуда: Made in USSR
Контактная информация:

Не используются ключи

Непрочитанное сообщение Alex Keda » 2010-04-16 15:10:09

вот такое поделие, написанное кода-то давно. и, помоему, раньше ключи использовались.
а может и нет. в любом случае - посещаемость возрасла и я заметил что таблица постоянно пилиться...
начал ковыряться - а тут такое

Код: Выделить всё

mysql> desc counter_segodnya;
+-----------------+-------------+------+-----+------------+----------------+
| Field           | Type        | Null | Key | Default    | Extra          |
+-----------------+-------------+------+-----+------------+----------------+
| id_zapisi       | int(15)     | NO   | PRI | NULL       | auto_increment |
| chislo          | date        | NO   |     | 0000-00-00 |                |
| vremya          | time        | NO   |     | 00:00:00   |                |
| vizit_timestamp | int(16)     | NO   | MUL | 0          |                |
| random_for_jaba | varchar(64) | NO   | MUL | 0          |                |
| ip              | varchar(15) | NO   | MUL |            |                |
| page            | int(5)      | NO   |     | 0          |                |
| user_agent      | text        | NO   |     | NULL       |                |
| referer         | text        | NO   |     | NULL       |                |
| screen_width    | int(6)      | NO   |     | 0          |                |
| screen_height   | int(6)      | NO   |     | 0          |                |
| user_color      | int(6)      | NO   |     | 0          |                |
| word_counter    | int(1)      | NO   | MUL | 0          |                |
+-----------------+-------------+------+-----+------------+----------------+
13 rows in set (0.00 sec)

mysql> explain SELECT COUNT(DISTINCT `ip`) AS `IP_this_day` FROM `counter_segodnya1` WHERE `vizit_timestamp` > '1271361600';
+----+-------------+-------------------+------+-----------------+------+---------+------+--------+-------------+
| id | select_type | table             | type | possible_keys   | key  | key_len | ref  | rows   | Extra       |
+----+-------------+-------------------+------+-----------------+------+---------+------+--------+-------------+
|  1 | SIMPLE      | counter_segodnya1 | ALL  | vizit_timestamp | NULL | NULL    | NULL | 106413 | Using where |
+----+-------------+-------------------+------+-----------------+------+---------+------+--------+-------------+
1 row in set (0.00 sec)
думал из-за условия, но - такое работает нормально.

Код: Выделить всё

mysql> explain SELECT COUNT(DISTINCT `ip`) AS `IP_this_day` FROM `counter_segodnya1` WHERE IP='123';
+----+-------------+-------------------+------+---------------+------+---------+-------+------+--------------------------+
| id | select_type | table             | type | possible_keys | key  | key_len | ref   | rows | Extra                    |
+----+-------------+-------------------+------+---------------+------+---------+-------+------+--------------------------+
|  1 | SIMPLE      | counter_segodnya1 | ref  | ip            | ip   | 17      | const |    1 | Using where; Using index |
+----+-------------+-------------------+------+---------------+------+---------+-------+------+--------------------------+
1 row in set (0.00 sec)

mysql>    
Убей их всех! Бог потом рассортирует...

Хостинговая компания Host-Food.ru
Хостинг HostFood.ru
 

Услуги хостинговой компании Host-Food.ru

Хостинг HostFood.ru

Тарифы на хостинг в России, от 12 рублей: https://www.host-food.ru/tariffs/hosting/
Тарифы на виртуальные сервера (VPS/VDS/KVM) в РФ, от 189 руб.: https://www.host-food.ru/tariffs/virtualny-server-vps/
Выделенные сервера, Россия, Москва, от 2000 рублей (HP Proliant G5, Intel Xeon E5430 (2.66GHz, Quad-Core, 12Mb), 8Gb RAM, 2x300Gb SAS HDD, P400i, 512Mb, BBU):
https://www.host-food.ru/tariffs/vydelennyi-server-ds/
Недорогие домены в популярных зонах: https://www.host-food.ru/domains/

Аватара пользователя
Fastman
ст. лейтенант
Сообщения: 1236
Зарегистрирован: 2006-07-07 10:20:38
Откуда: Минск. РБ

Re: Не используются ключи

Непрочитанное сообщение Fastman » 2010-04-16 18:32:56

А если явно указать USE INDEX (...)
Просто есть мулька что если использование индекса требует от MySQL прохода более чем по 30% строк в данной таблице то даже при возможности юзания оного, реально индекс юзаться не будет.
Главное в жизни здоровье и любовь, остальное я все куплю.

Аватара пользователя
Alex Keda
стреляли...
Сообщения: 35428
Зарегистрирован: 2004-10-18 14:25:19
Откуда: Made in USSR
Контактная информация:

Re: Не используются ключи

Непрочитанное сообщение Alex Keda » 2010-04-16 18:46:20

Код: Выделить всё

mysql> explain SELECT COUNT(DISTINCT `ip`) AS `IP_this_day` FROM `counter_segodnya` WHERE `vizit_timestamp` > '1271361600 USE INDEX ip';
+----+-------------+------------------+------+-----------------+------+---------+------+--------+-------------+
| id | select_type | table            | type | possible_keys   | key  | key_len | ref  | rows   | Extra       |
+----+-------------+------------------+------+-----------------+------+---------+------+--------+-------------+
|  1 | SIMPLE      | counter_segodnya | ALL  | vizit_timestamp | NULL | NULL    | NULL | 123195 | Using where |
+----+-------------+------------------+------+-----------------+------+---------+------+--------+-------------+
1 row in set, 1 warning (0.00 sec)

mysql> explain SELECT COUNT(DISTINCT `ip`) AS `IP_this_day` FROM `counter_segodnya` WHERE `vizit_timestamp` > '1271361600 USE INDEX vizit_timestamp';
+----+-------------+------------------+------+-----------------+------+---------+------+--------+-------------+
| id | select_type | table            | type | possible_keys   | key  | key_len | ref  | rows   | Extra       |
+----+-------------+------------------+------+-----------------+------+---------+------+--------+-------------+
|  1 | SIMPLE      | counter_segodnya | ALL  | vizit_timestamp | NULL | NULL    | NULL | 123197 | Using where |
+----+-------------+------------------+------+-----------------+------+---------+------+--------+-------------+
1 row in set, 1 warning (0.00 sec)

mysql>    
Убей их всех! Бог потом рассортирует...

Аватара пользователя
dikens3
подполковник
Сообщения: 4856
Зарегистрирован: 2006-09-06 16:24:08
Откуда: Нижний Новгород
Контактная информация:

Re: Не используются ключи

Непрочитанное сообщение dikens3 » 2010-04-16 20:03:49

)) Юзайте postgresql... )) В mysql оптимизатор гавно. Думаю из-за знака ">"
Балуйся ключами, я так делал.
Лучше установить FreeBSD, чем потратить 30 лет на Linux'ы и выяснить какой из них хуже.

Аватара пользователя
Fastman
ст. лейтенант
Сообщения: 1236
Зарегистрирован: 2006-07-07 10:20:38
Откуда: Минск. РБ

Re: Не используются ключи

Непрочитанное сообщение Fastman » 2010-04-16 20:16:48

dikens3 писал(а):)) Юзайте postgresql... )) В mysql оптимизатор гавно. Думаю из-за знака ">"
Балуйся ключами, я так делал.
Причина всегда есть. Если мы ее не знаем это не значит что MySQL Говно...
Вообщем я пас если честно... опыта в MySQL не много....
Главное в жизни здоровье и любовь, остальное я все куплю.

Аватара пользователя
dikens3
подполковник
Сообщения: 4856
Зарегистрирован: 2006-09-06 16:24:08
Откуда: Нижний Новгород
Контактная информация:

Re: Не используются ключи

Непрочитанное сообщение dikens3 » 2010-04-16 23:00:53

Если мы ее не знаем это не значит что MySQL Говно...
Не mysql, а оптимизатор - который решает как и какие ключи использовать.
Лучше установить FreeBSD, чем потратить 30 лет на Linux'ы и выяснить какой из них хуже.

Аватара пользователя
Alex Keda
стреляли...
Сообщения: 35428
Зарегистрирован: 2004-10-18 14:25:19
Откуда: Made in USSR
Контактная информация:

Re: Не используются ключи

Непрочитанное сообщение Alex Keda » 2010-04-17 8:46:41

так тоже некатит

Код: Выделить всё

mysql> explain SELECT COUNT(DISTINCT `ip`) AS `IP_this_day` FROM `counter_segodnya` WHERE `vizit_timestamp` between '1271361600' and 10000000000;
+----+-------------+------------------+------+-----------------+------+---------+------+--------+-------------+
| id | select_type | table            | type | possible_keys   | key  | key_len | ref  | rows   | Extra       |
+----+-------------+------------------+------+-----------------+------+---------+------+--------+-------------+
|  1 | SIMPLE      | counter_segodnya | ALL  | vizit_timestamp | NULL | NULL    | NULL | 130678 | Using where |
+----+-------------+------------------+------+-----------------+------+---------+------+--------+-------------+
1 row in set (0.01 sec)

mysql>   
Убей их всех! Бог потом рассортирует...

Аватара пользователя
dikens3
подполковник
Сообщения: 4856
Зарегистрирован: 2006-09-06 16:24:08
Откуда: Нижний Новгород
Контактная информация:

Re: Не используются ключи

Непрочитанное сообщение dikens3 » 2010-04-17 11:26:37

Я знаешь как решил свою проблему? Создал ещё один столбец(всегда одинаковый) и создал двойной ключ.

Т.е. у тебя есть:
Столбец X (нужный тебе и не работающий с индексом)
+ Новый столбец (скажем писать туда 1)

Ключ одновременно на оба.

Потом делал если СТАРОЕ_УСЛОВИЕ и НОВЫЙСТОЛБЕЦ=1

Что-то типа того:

Код: Выделить всё

# Создаём таблицу логов.
DROP TABLE IF EXISTS `log`;
CREATE TABLE `log` (
  `username` varchar(50) default NULL,
  `action` smallint(6) unsigned NOT NULL default '0',
  `src_email` varchar(50) default NULL,
  `dst_email` varchar(50) default NULL,
  `src_ip` varchar(15) default NULL,
  `hostname` varchar(255) default NULL,
  `helo` varchar(255) default NULL,
  `date` date default NULL,
  `size` int(11) default NULL,
  `time` timestamp NOT NULL default '',
  KEY `size-date` (`size`,`date`),
  KEY `action-date` (`action`,`date`),
  KEY `size` (`size`),
  KEY `date` (`date`)
) ENGINE=MyISAM DEFAULT CHARSET=koi8r COMMENT='Таблица логов';
Лучше установить FreeBSD, чем потратить 30 лет на Linux'ы и выяснить какой из них хуже.