|
|
|
Скорость выполнения запроса (Большая таблица)
|
|||
|---|---|---|---|
|
#18+
Здравствуйте. Есть 1 большая таблица, в которой сейчас записей 17млн. Будет 200 млн записей через пару дней, когда мы зальем остальную информацию. В дальнейшем в день таблица будет пополняться на 700к записей. p1-p9 - это игрок в карты, который может сидеть на разном месте в раздаче за столом. psd и pp - просто статы, как сыграл. handLimit - лимит раздачи. Нужно доставать информацию настолько быстро, на сколько это возможно. В таблице есть составной индекс p*_handLimit , чаще всего выборка будет работать именно по p* + handLimit , но если попытаться выбрать все записи с игроком, то запрос уже сейчас занимает 1.25с. Т.е. в будущем запрос может длиться и 5+ секунд. Игрок записан в mediumint 3 байта. Сам запрос: авторSELECT `id`, `currency`, `pp1` AS `profit`, `psd1` AS `isSD`, `handLimit` FROM `ps_hands` WHERE `p1` = '9121' UNION ALL (SELECT `id`, `currency`, `pp2` AS `profit`, `psd2` AS `isSD`, `handLimit` FROM `ps_hands` WHERE `p2` = '9121') UNION ALL (SELECT `id`, `currency`, `pp3` AS `profit`, `psd3` AS `isSD`, `handLimit` FROM `ps_hands` WHERE `p3` = '9121') UNION ALL (SELECT `id`, `currency`, `pp4` AS `profit`, `psd4` AS `isSD`, `handLimit` FROM `ps_hands` WHERE `p4` = '9121') UNION ALL (SELECT `id`, `currency`, `pp5` AS `profit`, `psd5` AS `isSD`, `handLimit` FROM `ps_hands` WHERE `p5` = '9121') UNION ALL (SELECT `id`, `currency`, `pp6` AS `profit`, `psd6` AS `isSD`, `handLimit` FROM `ps_hands` WHERE `p6` = '9121') UNION ALL (SELECT `id`, `currency`, `pp7` AS `profit`, `psd7` AS `isSD`, `handLimit` FROM `ps_hands` WHERE `p7` = '9121') UNION ALL (SELECT `id`, `currency`, `pp8` AS `profit`, `psd8` AS `isSD`, `handLimit` FROM `ps_hands` WHERE `p8` = '9121') UNION ALL (SELECT `id`, `currency`, `pp9` AS `profit`, `psd9` AS `isSD`, `handLimit` FROM `ps_hands` WHERE `p9` = '9121') ORDER BY `id` ASC Использую юнион, Потому что обычный OR OR OR ... медленнее на 30%. Движок MyISAM , важен только селект и инсерт. Апдейтов никогда не будет, а заноситься значения будут раз в день 1 минуту по времени. my.cnf настроен не знаю как, пару лет назад что-то там пытался, таким он и остался. Серверная машина - 128гб оперы, 16 потоков 8 ядер. И соответственно EXPLAIN запроса и стуктуру таблицы приложил в изображениях: ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.09.2018, 22:25 |
|
||
|
Скорость выполнения запроса (Большая таблица)
|
|||
|---|---|---|---|
|
#18+
8POWER-, Покажите нормальный DDL таблицы текстом. Разглядывать мелкий мутный jpeg не очень-то хочется. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.09.2018, 22:35 |
|
||
|
Скорость выполнения запроса (Большая таблица)
|
|||
|---|---|---|---|
|
#18+
Вообще таблица просится на "разворот" в вертикаль и на отделение результатов игроков в отдельную таблицу. Тогда всех этих UNION ALL-ов будет не нужно. И индекс будет нужен один вместо девяти. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.09.2018, 22:44 |
|
||
|
Скорость выполнения запроса (Большая таблица)
|
|||
|---|---|---|---|
|
#18+
Упс, это старая таблица. Прошу прощения. Вот новая Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.09.2018, 22:49 |
|
||
|
Скорость выполнения запроса (Большая таблица)
|
|||
|---|---|---|---|
|
#18+
miksoftВообще таблица просится на "разворот" в вертикаль и на отделение результатов игроков в отдельную таблицу. Тогда всех этих UNION ALL-ов будет не нужно. И индекс будет нужен один вместо девяти. Честно? Я не представляю как это реализовать :( Пытаюсь, но пока не получается. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.09.2018, 22:52 |
|
||
|
Скорость выполнения запроса (Большая таблица)
|
|||
|---|---|---|---|
|
#18+
8POWER-, Помимо предыдущего замечания: Вы уверены, что нужно использовать именно float? 4 байта как-никак... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.09.2018, 22:54 |
|
||
|
Скорость выполнения запроса (Большая таблица)
|
|||
|---|---|---|---|
|
#18+
8POWER-miksoftВообще таблица просится на "разворот" в вертикаль и на отделение результатов игроков в отдельную таблицу. Тогда всех этих UNION ALL-ов будет не нужно. И индекс будет нужен один вместо девяти. Честно? Я не представляю как это реализовать :( Пытаюсь, но пока не получается.одна запись в таблицу партий и 9 записей в таблицу игроков-партий. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.09.2018, 22:56 |
|
||
|
Скорость выполнения запроса (Большая таблица)
|
|||
|---|---|---|---|
|
#18+
miksoft8POWER-, Помимо предыдущего замечания: Вы уверены, что нужно использовать именно float? 4 байта как-никак... Смотрите, я вчера думал о том, чтобы урезать handLimit с флоат до smaillint , итого экономлю 2 байта * строки. Возможно так и поступлю, а умножать на 100 буду в пхп. Но, профит как использовать не флоат? Если допустим писать в центах вместо 1.01 , понимаю, но если игрок выиграл 150000$ , это я не преувеличил, действительно в день есть больше 50 выигрышей от 80к+$. То тогда не влезет запись и все равно придется 4 байта уже отдавать( ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.09.2018, 22:57 |
|
||
|
Скорость выполнения запроса (Большая таблица)
|
|||
|---|---|---|---|
|
#18+
8POWER-Но, профит как использовать не флоат? Если допустим писать в центах вместо 1.01 , понимаю, но если игрок выиграл 150000$ , это я не преувеличил, действительно в день есть больше 50 выигрышей от 80к+$. То тогда не влезет запись и все равно придется 4 байта уже отдавать(Даже в этом случае float плохой выбор, если не хотите потом удивляться, почему у вас 0.1+0.1=0.19999..., а не 0.2. Для денег лучше использовать либо более приспособленные типы, например, DECIMAL, либо целочисленные в нужном масштабе. Для масштаба 0.01 ... 150000 хватит типа MEDIUMINT, правда, без запаса. INT - с запасом. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.09.2018, 23:10 |
|
||
|
Скорость выполнения запроса (Большая таблица)
|
|||
|---|---|---|---|
|
#18+
Что такое psd1-9 и зачем их столько? currency явно просится tinyint, да и вообще, нужно ли это поле? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.09.2018, 23:11 |
|
||
|
Скорость выполнения запроса (Большая таблица)
|
|||
|---|---|---|---|
|
#18+
Код: sql 1. отдельно этот фрагмент за какое время выполняется? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.09.2018, 23:13 |
|
||
|
Скорость выполнения запроса (Большая таблица)
|
|||
|---|---|---|---|
|
#18+
miksoft8POWER-Но, профит как использовать не флоат? Если допустим писать в центах вместо 1.01 , понимаю, но если игрок выиграл 150000$ , это я не преувеличил, действительно в день есть больше 50 выигрышей от 80к+$. То тогда не влезет запись и все равно придется 4 байта уже отдавать(Даже в этом случае float плохой выбор, если не хотите потом удивляться, почему у вас 0.1+0.1=0.19999..., а не 0.2. Для денег лучше использовать либо более приспособленные типы, например, DECIMAL, либо целочисленные в нужном масштабе. Для масштаба 0.01 ... 150000 хватит типа MEDIUMINT, правда, без запаса. INT - с запасом. Да судя по mysql.com, mediumint хватит в Maximum Unsigned value , а это не вредно? Я обычно по Maximum Value ориентировался. сейчас посмотрю какие максимальные выигрыши были за 17млн. Про 0.1 + 0.1 - уже удивлялись, поэтому округляли и качали bmath для php , mysql - javascript #2 :D ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.09.2018, 23:14 |
|
||
|
Скорость выполнения запроса (Большая таблица)
|
|||
|---|---|---|---|
|
#18+
miksoft Код: sql 1. отдельно этот фрагмент за какое время выполняется? SELECT SQL_NO_CACHE `id`, `currency`, `pp1` AS `profit`, `psd1` AS `isSD`, `handLimit` FROM `ps_hands` WHERE `p1` = '9121' Total execution time in seconds: 0.11549305915833 Если в кеше запрос - то 0.02 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.09.2018, 23:15 |
|
||
|
Скорость выполнения запроса (Большая таблица)
|
|||
|---|---|---|---|
|
#18+
8POWER-, И еще - план показывает оценку порядка 300 тысяч записей в результате (сумма колонки rows). Вам точно нужны все эти записи? Да еще в отсортированном виде? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.09.2018, 23:16 |
|
||
|
Скорость выполнения запроса (Большая таблица)
|
|||
|---|---|---|---|
|
#18+
8POWER-Да судя по mysql.com, mediumint хватит в Maximum Unsigned value , а это не вредно?Не понял, что именно может быть вредно? Либо вам хватает диапазона и точности, либо нет. Диапазоны целочисленных типов . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.09.2018, 23:19 |
|
||
|
Скорость выполнения запроса (Большая таблица)
|
|||
|---|---|---|---|
|
#18+
miksoft8POWER-, И еще - план показывает оценку порядка 300 тысяч записей в результате (сумма колонки rows). Вам точно нужны все эти записи? Да еще в отсортированном виде? Да, нужно получать все данные, если пользователь указал фильтр за всё время, сортировка так же нужна для построения графика. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.09.2018, 23:22 |
|
||
|
Скорость выполнения запроса (Большая таблица)
|
|||
|---|---|---|---|
|
#18+
miksoft8POWER-Да судя по mysql.com, mediumint хватит в Maximum Unsigned value , а это не вредно?Не понял, что именно может быть вредно? Либо вам хватает диапазона и точности, либо нет. Диапазоны целочисленных типов . Не подходит unsigned, так как профит игрока может быть отрицательным. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.09.2018, 23:23 |
|
||
|
Скорость выполнения запроса (Большая таблица)
|
|||
|---|---|---|---|
|
#18+
8POWER-Не подходит unsigned, так как профит игрока может быть отрицательным.Тогда INT или DECIMAL. Но все равно не FLOAT. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.09.2018, 23:26 |
|
||
|
Скорость выполнения запроса (Большая таблица)
|
|||
|---|---|---|---|
|
#18+
8POWER-miksoft8POWER-, И еще - план показывает оценку порядка 300 тысяч записей в результате (сумма колонки rows). Вам точно нужны все эти записи? Да еще в отсортированном виде? Да, нужно получать все данные, если пользователь указал фильтр за всё время, сортировка так же нужна для построения графика.С этим надо что-то делать. Никакой пользователь не будет читать сотни тысяч записей и никакой экран не покажет график из сотен тысяч точек. Либо отказывать пользователю в таком запросе, либо показывать предагрегированные данные, либо что-то еще. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.09.2018, 23:28 |
|
||
|
Скорость выполнения запроса (Большая таблица)
|
|||
|---|---|---|---|
|
#18+
8POWER-, Показанный запрос - единственный тип запросов, которые будут выполняться или есть и другие? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.09.2018, 23:34 |
|
||
|
Скорость выполнения запроса (Большая таблица)
|
|||
|---|---|---|---|
|
#18+
miksoft8POWER-пропущено... Да, нужно получать все данные, если пользователь указал фильтр за всё время, сортировка так же нужна для построения графика.С этим надо что-то делать. Никакой пользователь не будет читать сотни тысяч записей и никакой экран не покажет график из сотен тысяч точек. Либо отказывать пользователю в таком запросе, либо показывать предагрегированные данные, либо что-то еще. Мы не отдаём пользователю все точки, однако нам они нужны чтобы подсчитать каждую и вывести ему график со всеми результатами. Данные разделяются на 1 тысячу точек, а при приближении любой части графика - рендерятся новые точки. К тому же пользователь запрашивает даже не 300тыс. записей, а может и 2млн запросить, если у оппонента наиграно столько рук и ему нужна статистика за все время.. А в 90% случаях нужна. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.09.2018, 23:39 |
|
||
|
Скорость выполнения запроса (Большая таблица)
|
|||
|---|---|---|---|
|
#18+
miksoft8POWER-, Показанный запрос - единственный тип запросов, которые будут выполняться или есть и другие? Только такой тип. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.09.2018, 23:40 |
|
||
|
Скорость выполнения запроса (Большая таблица)
|
|||
|---|---|---|---|
|
#18+
8POWER-Мы не отдаём пользователю все точки, однако нам они нужны чтобы подсчитать каждую и вывести ему график со всеми результатами. Данные разделяются на 1 тысячу точек, а при приближении любой части графика - рендерятся новые точки.Вполне вероятно, что вам помогут предагрегаты. Если, конечно, возможно заранее как-то определить интервалы группировки. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.09.2018, 23:54 |
|
||
|
Скорость выполнения запроса (Большая таблица)
|
|||
|---|---|---|---|
|
#18+
8POWER-miksoft8POWER-, Показанный запрос - единственный тип запросов, которые будут выполняться или есть и другие? Только такой тип.Тогда я бы попробовал разделить таблицу на две, как писал выше - 21687504 . И, возможно, перейти на InnoDB. Он может быть быстрее при выборке по первичному ключу. Но, конечно, нужно делать тесты. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.09.2018, 23:56 |
|
||
|
Скорость выполнения запроса (Большая таблица)
|
|||
|---|---|---|---|
|
#18+
miksoft8POWER-пропущено... Только такой тип.Тогда я бы попробовал разделить таблицу на две, как писал выше - 21687504 . И, возможно, перейти на InnoDB. Он может быть быстрее при выборке по первичному ключу. Но, конечно, нужно делать тесты. Хорошо, спасибо ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.09.2018, 23:58 |
|
||
|
Скорость выполнения запроса (Большая таблица)
|
|||
|---|---|---|---|
|
#18+
Проработав все о чем поговорили, кроме смещения таблицы с горизонтальной в вертикальную, получилось добиться результата этого же запроса вместо 0.64-0.75с вместо 1.25с. Проглядел, что maxPlayers стоял int , убрал float на profit в mediumint , currency теперь не $ а 1 и что-то еще, уже подзабыл. Долго возился с настройками MySQL сегодня, заметил вот такую вещь: # Query_time: 3.964766 Lock_time: 0.000197 Rows_sent: 1051346 Rows_examined: 3154038 SET timestamp=1538129731; SELECT SQL_NO_CACHE `id`, `currency`, `pp1` AS `profit`, `psd1` AS `isSD`, `handLimit` FROM `ps_hands` WHERE `p1` = '96317' UNION ALL (SELECT `id`, `currency`, `pp2` AS `profit`, `psd2` AS `isSD`, `handLimit` FROM `ps_hands` WHERE `p2` = '96317') UNION ALL (SELECT `id`, `currency`, `pp3` AS `profit`, `psd3` AS `isSD`, `handLimit` FROM `ps_hands` WHERE `p3` = '96317') UNION ALL (SELECT `id`, `currency`, `pp4` AS `profit`, `psd4` AS `isSD`, `handLimit` FROM `ps_hands` WHERE `p4` = '96317') UNION ALL (SELECT `id`, `currency`, `pp5` AS `profit`, `psd5` AS `isSD`, `handLimit` FROM `ps_hands` WHERE `p5` = '96317') UNION ALL (SELECT `id`, `currency`, `pp6` AS `profit`, `psd6` AS `isSD`, `handLimit` FROM `ps_hands` WHERE `p6` = '96317') UNION ALL (SELECT `id`, `currency`, `pp7` AS `profit`, `psd7` AS `isSD`, `handLimit` FROM `ps_hands` WHERE `p7` = '96317') UNION ALL (SELECT `id`, `currency`, `pp8` AS `profit`, `psd8` AS `isSD`, `handLimit` FROM `ps_hands` WHERE `p8` = '96317') UNION ALL (SELECT `id`, `currency`, `pp9` AS `profit`, `psd9` AS `isSD`, `handLimit` FROM `ps_hands` WHERE `p9` = '96317') ORDER BY `id` ASC; Этот запрос на самого крутого(по количеству игр) на данный момент игрока выполняется 3.5-4.3сек. Слоу лог: Rows_sent: 1051346 Rows_examined: 3154038 Как это возможно? У меня проиндексирован p1-p9 , он ведь должен читать всего 1051346 строк, вместо 3 миллионов? Почему он читает еще 2 миллиона? Если через OR OR OR то вообще 5 млн и скорость запроса в 2 раза хуже. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.09.2018, 13:24 |
|
||
|
Скорость выполнения запроса (Большая таблица)
|
|||
|---|---|---|---|
|
#18+
В таблице сейчас 66 млн строк... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.09.2018, 13:32 |
|
||
|
Скорость выполнения запроса (Большая таблица)
|
|||
|---|---|---|---|
|
#18+
8POWER-Слоу лог: Rows_sent: 1051346 Rows_examined: 3154038 Как это возможно? У меня проиндексирован p1-p9 , он ведь должен читать всего 1051346 строк, вместо 3 миллионов?Судя по тому, что числа различаются ровно в 3 раза, это какой-то эффект самого MySQL. Например, либо от UNION ALL-ов, либо от сортировки, либо от обоих. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.09.2018, 23:09 |
|
||
|
Скорость выполнения запроса (Большая таблица)
|
|||
|---|---|---|---|
|
#18+
miksoft8POWER-Слоу лог: Rows_sent: 1051346 Rows_examined: 3154038 Как это возможно? У меня проиндексирован p1-p9 , он ведь должен читать всего 1051346 строк, вместо 3 миллионов?Судя по тому, что числа различаются ровно в 3 раза, это какой-то эффект самого MySQL. Например, либо от UNION ALL-ов, либо от сортировки, либо от обоих. Судя по всему реально так. Убрал юнионы: Код: sql 1. 2. 3. Затем убрал ордер и стало ровно в ровно строчек..: Код: sql 1. 2. 3. Затем все вернул обратно: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. И результат, как из этого видно - юнионы быстрее, даже с ордером.. Эх. Спасибо за помощь. Не знал. А вам надо идти в майкрософт работать) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.09.2018, 23:53 |
|
||
|
Скорость выполнения запроса (Большая таблица)
|
|||
|---|---|---|---|
|
#18+
Попытался еще поднастроить my.cnf , с помощью mysqltuner но долго думав понял, что тут и я болван и тюнер. Т.к. он не знает, какая у меня непростая задача) а я потому, что боюсь сервер скоро сгорит от того, что я "типо" настроил.. Ха-ха. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.09.2018, 23:54 |
|
||
|
|

start [/forum/topic.php?all=1&fid=47&tid=1829576]: |
0ms |
get settings: |
10ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
34ms |
get topic data: |
10ms |
get forum data: |
3ms |
get page messages: |
60ms |
get tp. blocked users: |
1ms |
| others: | 13ms |
| total: | 153ms |

| 0 / 0 |

Извините, этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
... ля, ля, ля ...