Модераторы: skyboy

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> индексы и терминология 
V
    Опции темы
bars80080
Дата 25.2.2013, 09:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прапор творюет
****
Награды: 1



Профиль
Группа: Завсегдатай
Сообщений: 12022
Регистрация: 5.12.2007
Где: Königsberg

Репутация: 5
Всего: 315



на хостинге у меня выполняется раз в 15-20 мин такой запрос

DELETE FROM `ws_flights` WHERE `date`<1361518163;

в таблице при этом находится порядка 30000 - 50000 строк.
дабы ускорить его выполнение был добавлен индекс KEY `DATE` (`date`):

Код

CREATE TABLE `ws_flights` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `date` int(11) unsigned DEFAULT '0',
  `sid` int(11) unsigned DEFAULT '0',
  `flight` text,
  `price` decimal(10,2) unsigned DEFAULT '0.00',
  PRIMARY KEY (`id`),
  KEY `SID_PRICE` (`sid`,`price`),
  KEY `DATE` (`date`)
) ENGINE=MyISAM AUTO_INCREMENT=232847498 DEFAULT CHARSET=utf8


вопросы:

1. можно ли ещё что-то сделать для оптимизации? так как хостер жалуется что слишком много строк постоянно проверяется, в силу чего он отключает сайт и тогда жалуемся мы
2. чисто вопрос по терминологии: KEY `DATE` (`date`) - это индекс или нет? или просто ключ?
PM MAIL WWW   Вверх
Akina
Дата 25.2.2013, 09:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 106
Всего: 454



Цитата(bars80080 @  25.2.2013,  10:28 Найти цитируемый пост)
можно ли ещё что-то сделать для оптимизации?

Я бы предложил попробовать создать индекс по (`date`,id) и получать в подзапросе перечень ID к удалению...

Код

DELETE FROM `ws_flights` 
WHERE id IN (
             SELECT id 
             FROM `ws_flights` 
             WHERE `date`<1361518163
             ) subquery;


Либо то же, но JOIN, может, даже вьюшка...

Добавлено @ 10:01
PS. А какой процент записей удаляется? 
PPS. И вообще - поясните суть происходящего... если это тупо чистка лога - перейдите на лог постоянного объёма, и вместо удаления и вставки апдейтите просто самую старую запись.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
bars80080
Дата 25.2.2013, 11:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прапор творюет
****
Награды: 1



Профиль
Группа: Завсегдатай
Сообщений: 12022
Регистрация: 5.12.2007
Где: Königsberg

Репутация: 5
Всего: 315



это таблица сохраняемых результатов поиска из удалённой системы.

поиск происходит настолько часто, что инкремент уже накрутил 232 млн записей. мы за месяц без чистки таблицы упираемся в разрешённые объёмы базы данных. и при этом по таблице постоянно происходит поиск по запросу:

Код

SELECT * FROM `ws_flights` WHERE `sid`=789456 ORDER BY `price`


именно этот запрос вначале вызвал проблемы с хостингом. к счастью, данные сами по себе актуальны в пределах часа и хранить их более не нужно, поэтому мы стали удалять их. но так как это тоже затратная операция, то ввели периодичность раз в 15-20 минут, но и на это ругается хостер.

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



Код

DELETE FROM `ws_flights` 
WHERE id IN (
             SELECT id 
             FROM `ws_flights` 
             WHERE `date`<1361518163
             ) subquery;

а этот запрос покатит, если SELECT id FROM `ws_flights` WHERE `date`<1361518163 соберёт до 20000 id-шников?
PM MAIL WWW   Вверх
Akina
Дата 25.2.2013, 11:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 106
Всего: 454



Цитата(bars80080 @  25.2.2013,  12:24 Найти цитируемый пост)
за час может набраться до 70000 строк

Вывод - удалять надо ежеминутно или даже чаще (версия сервера эвенты поддерживает? а права есть?). Тогда мой запрос даст нормальные результаты. При 1.7% и более высокой селективности метод будет достаточно эффективен.
Либо, как я указал выше, хранить постоянное количество записей (скажем, 100 тыс.), и не удалять-добавлять, а апдейтить самую старую.

Это сообщение отредактировал(а) Akina - 25.2.2013, 11:53


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
bars80080
Дата 25.2.2013, 12:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прапор творюет
****
Награды: 1



Профиль
Группа: Завсегдатай
Сообщений: 12022
Регистрация: 5.12.2007
Где: Königsberg

Репутация: 5
Всего: 315



Цитата(Akina @  25.2.2013,  11:50 Найти цитируемый пост)
Вывод - удалять надо ежеминутно или даже чаще

мне нужно хранить данные в пределах не менее часа


Цитата(Akina @  25.2.2013,  11:50 Найти цитируемый пост)
При 1.7% и более высокой селективности метод будет достаточно эффективен.

так если раз в 15-20 мин, то удаляется порядка 25% записей


Цитата(Akina @  25.2.2013,  11:50 Найти цитируемый пост)
версия сервера эвенты поддерживает? а права есть?

пока сказать не могу, не пробовал.


Цитата(Akina @  25.2.2013,  11:50 Найти цитируемый пост)
Либо, как я указал выше, хранить постоянное количество записей (скажем, 100 тыс.), и не удалять-добавлять, а апдейтить самую старую.

подумаю над реорганизацией
PM MAIL WWW   Вверх
Akina
Дата 25.2.2013, 12:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 106
Всего: 454



Цитата(bars80080 @  25.2.2013,  13:02 Найти цитируемый пост)
мне нужно хранить данные в пределах не менее часа

Я разве сказал, что всё? удаляй раз в минуту то, что старше часа от роду...

Цитата(bars80080 @  25.2.2013,  13:02 Найти цитируемый пост)
если раз в 15-20 мин, то удаляется порядка 25% записей

Фуллскан таблицы, файлсорт при отборе... у хостера есть все основания материть тебя...

Добавлено через 3 минуты и 9 секунд
Код

DELETE FROM `ws_flights` 
WHERE id IN (
             SELECT id 
             FROM `ws_flights` 
             WHERE `date`< NOW() - INTERVAL 1 HOURS
             ) subquery;


Добавлено через 5 минут и 26 секунд
Код

delimiter |

CREATE EVENT clear_ws_flights
ON SCHEDULE EVERY 1 MINUTE DO
DELETE FROM `ws_flights` 
WHERE id IN (
             SELECT id 
             FROM `ws_flights` 
             WHERE `date`< NOW() - INTERVAL 1 HOURS
             ) subquery;
END |

delimiter ;



--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Zloxa
Дата 25.2.2013, 14:14 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 33
Всего: 161



Цитата(Akina @  25.2.2013,  10:59 Найти цитируемый пост)
Я бы предложил попробовать создать индекс по (`date`,id) и получать в подзапросе перечень ID к удалению...

Я могу ошибаться в силу плохого знания специфики MySQL, но, кажется, где-то читал, что индексы в нем, де факто являются кластерными, т.е. де факто содержат в хвосте значения ПК. Опять же, могу ошибаться, но кажется, я читал что это одинаково реализовано и в MyISAM и в InnoDB. Если это действительно так, и добавление в хвост значения PK не будет оптимизировано движком, то данным решением будет достигнут чистый оверхед без какого бы то ни было профита.


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
Akina
Дата 25.2.2013, 14:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 106
Всего: 454



Цитата(Zloxa @  25.2.2013,  15:14 Найти цитируемый пост)
де факто содержат в хвосте значения ПК

Почти да. Они содержат внутренний уникальный номер записи. С ПК, кстати, не связанный.

Цитата(Zloxa @  25.2.2013,  15:14 Найти цитируемый пост)
индексы в нем, де факто являются кластерными

Только для InnoDB. И то с выпендронами.
Цитата(http://dev.mysql.com/doc/refman/5.5/en/innodb-index-types.html)

Every InnoDB table has a special index called the clustered index where the data for the rows is stored. Typically, the clustered index is synonymous with the primary key. To get the best performance from queries, inserts, and other database operations, you must understand how InnoDB uses the clustered index to optimize the most common lookup and DML operations for each table. 
•If you define a PRIMARY KEY on your table, InnoDB uses it as the clustered index. Define a primary key for each table that you create. If there is no logical unique and non-null column or set of columns, add a new auto-increment column, whose values are filled in automatically. 
•If you do not define a PRIMARY KEY for your table, MySQL locates the first UNIQUE index where all the key columns are NOT NULL and InnoDB uses it as the clustered index. 
•If the table has no PRIMARY KEY or suitable UNIQUE index, InnoDB internally generates a hidden clustered index on a synthetic column containing row ID values. The rows are ordered by the ID that InnoDB assigns to the rows in such a table. The row ID is a 6-byte field that increases monotonically as new rows are inserted. Thus, the rows ordered by the row ID are physically in insertion order.



--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Zloxa
Дата 25.2.2013, 15:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 33
Всего: 161



Цитата(Akina @  25.2.2013,  15:41 Найти цитируемый пост)
Они содержат внутренний уникальный номер записи. С ПК, кстати, не связанный.

Если это так, сканирование индекса и доступ по адресу строки, должен бы быть эффективнее нежели сканирование, пусть и покрывающиего индеса, извлечение PK, скариноварие PK, доступ по адресу строки.

Цитата(Akina @  25.2.2013,  15:41 Найти цитируемый пост)
Только для InnoDB

Понял. Т.е. то жжж блыо про InnoDB только.

И да, я высказался сумбурно. Кластерный индекс, он на таблицу один и (что не совсем имхо правильно) в первую голову он - ПК. Остальные, не кластерные индексы рефают на него, т.е. не явно содержат значение кластерного индекса в хвосте.



--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
Akina
Дата 25.2.2013, 15:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 106
Всего: 454



Цитата(Zloxa @  25.2.2013,  16:04 Найти цитируемый пост)
Если это так, сканирование индекса и доступ по адресу строки, должен бы быть эффективнее нежели сканирование, пусть и покрывающиего индеса, извлечение PK, скариноварие PK, доступ по адресу строки

Я не знаю начинки механизма удаления записей, но там, судя по наблюдениям, вовсе не всё так оптимально и гладко, как хотелось бы... во всяком случае в версии 5.5. 
5.6 пока ещё не испытывал на этой операции - некогда было. Но появление просмотра плана запроса на удаление в версии внушает некоторый оптимизм.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
bars80080
Дата 25.2.2013, 16:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прапор творюет
****
Награды: 1



Профиль
Группа: Завсегдатай
Сообщений: 12022
Регистрация: 5.12.2007
Где: Königsberg

Репутация: 5
Всего: 315



Цитата(Akina @  25.2.2013,  12:04 Найти цитируемый пост)
Фуллскан таблицы, файлсорт при отборе... 

вот начиная с этой фразы я всё нижеследующее не осилил

короче, мне надо вместо

DELETE FROM `ws_flights` WHERE `date`<1361518163; раз в 15-20 минут

использовать раз в минуту

Код

DELETE FROM `ws_flights` 
WHERE id IN (
             SELECT id 
             FROM `ws_flights` 
             WHERE `date`< 1361518163
             ) subquery;

* `date`< 1361518163 - число из пхп подставляется

а "subquery" - команда или константа какая? или мне полагается что-то вставить на его место?
PM MAIL WWW   Вверх
Akina
Дата 25.2.2013, 17:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 106
Всего: 454



bars80080, раз в минуту тебе надо запускать запрос, который самый первый в области "ниасилил". Из PHP при этом ничего подставлять не нужно, запрос передавать "как есть". При необходимости - можно в тексте запроса изменить интервал и давать его в изменённом виде.
Если же тебе доступно создание эвентов - надо один раз запустить второй код из той же области, и он (точнее, созданное им задание) каждую минуту будет запускать первый (сам первый при этом запускать не нужно).
subquery - это алиас, необходимый для корректной обработки сервером запроса. Можно не менять, оставить как есть.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
bars80080
Дата 26.2.2013, 14:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прапор творюет
****
Награды: 1



Профиль
Группа: Завсегдатай
Сообщений: 12022
Регистрация: 5.12.2007
Где: Königsberg

Репутация: 5
Всего: 315



DELETE FROM `ws_flights` WHERE id IN (SELECT id FROM `ws_flights` WHERE `date`<1361868779) subquery
error: 1064
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'subquery' at line 1


DELETE FROM `ws_flights` WHERE `id` IN (SELECT `id` FROM `ws_flights` WHERE `date`< NOW() - INTERVAL 1 HOURS) subquery
error: 1064
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'HOURS) subquery' at line 1


DELETE FROM `ws_flights` WHERE `id` IN (SELECT `id` FROM `ws_flights` WHERE `date`< NOW() - INTERVAL 1 HOUR) subquery
error: 1064
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'subquery' at line 1


что-то не выходит
PM MAIL WWW   Вверх
Akina
Дата 26.2.2013, 15:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 106
Всего: 454



bars80080, всегда смотри, на что ругается сервер, ибо первый байт в кавычках - это первый байт того, что серверу не нравится.
Видимо, он не желает понимать алиас в выражении WHERE IN (я этим методом не пользуюсь. предпочитая JOIN - они обычно эффективнее, но там без алиасов никуда) - ну убери алиас...


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
bars80080
Дата 26.2.2013, 16:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прапор творюет
****
Награды: 1



Профиль
Группа: Завсегдатай
Сообщений: 12022
Регистрация: 5.12.2007
Где: Königsberg

Репутация: 5
Всего: 315



так что ли?

query:
DELETE FROM `ws_flights` WHERE `id` IN (SELECT `id` FROM `ws_flights` WHERE `date`< NOW() - INTERVAL 1 HOUR)
error: 1093
You can't specify target table 'ws_flights' for update in FROM clause

Добавлено через 26 секунд
query:
DELETE FROM `ws_flights` WHERE `id` IN (SELECT `id` FROM `ws_flights` WHERE `date`< NOW() - INTERVAL 1 HOURS)
error: 1064
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'HOURS)' at line 1
PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | MySQL | Следующая тема »


 




[ Время генерации скрипта: 0.0990 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.