powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Отимизация таблицы
11 сообщений из 11, страница 1 из 1
Отимизация таблицы
    #40123535
LentyMe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
есть таблица

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
CREATE TABLE pay_transaction (
  pay_transaction_id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
  parent_id BIGINT(20) UNSIGNED DEFAULT NULL,
  account_id BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
  system_id BIGINT(20) UNSIGNED NOT NULL,
  action_id VARCHAR(196) NOT NULL DEFAULT '0',
  action ENUM('1',2',3') DEFAULT NULL,
  external_user_id VARCHAR(40) DEFAULT NULL,
  session_id VARCHAR(50) DEFAULT NULL,
  data JSON NOT NULL,
  raw MEDIUMTEXT DEFAULT NULL,
  date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  created TIMESTAMP(4) NOT NULL DEFAULT CURRENT_TIMESTAMP(4),
  amount DECIMAL(20, 2) GENERATED ALWAYS AS (json_extract(`data`,_utf8'$.amount')) STORED,
  bonus DECIMAL(20, 2) GENERATED ALWAYS AS (json_extract(`data`,_utf8'$.bonus.amount')) STORED,
  original_action_id VARCHAR(255) GENERATED ALWAYS AS (json_unquote(json_extract(`data`,_utf8'$.original_action_id'))) VIRTUAL,
  day DATE GENERATED ALWAYS AS (cast(`date` as date)) STORED,
  PRIMARY KEY (pay_transaction_id, date),
  INDEX IDX_transaction_day(account_id, pay_transaction , day, action, system_id,  bonus, amount, parent_id)
)




В таблице порядка 8 миллионов записей

Простой запрос типа
Код: sql
1.
  SELECT  sum(pay_transaction .amount),sum(pay_transaction .bonus), sum(pay_transaction .bonus)   FROM pay_transaction   WHERE `pay_transaction `. day BETWEEN "2021-12-20" AND "2021-12-27" AND pay_transaction .action = '1' GROUP BY bet_transaction.account_id



выполняется порядка 6с

Explain показывает

Key key_len ref rows filtred Extra
IDX_transaction_day 68 (null) 8825447 3,7 Using where; Using index


innodb_buffer_pool_size 24 GB

Код: sql
1.
2.
SELECT FLOOR(SUM(data_length+index_length)/POWER(1024,2)) 
FROM information_schema.tables WHERE engine='InnoDB';


Результат:14038

Подскажите пожалуйста, что не так, почему так долго и можно ли ускорить выборку и что будет при увеличении количества данных ? Планируется 1-2 миллиона записей в сутки

PS Сервера Percona MYSQL на хецнере , 3 кластера галера
...
Рейтинг: 0 / 0
Отимизация таблицы
    #40123576
Gluck99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LentyMe
Код: sql
1.
action ENUM('1',2',3') DEFAULT NULL

Странное использование ENUM, причём в значении, по ходу дела, ошибка. Если поле просто числовое, то его и надо делать числовым, например, TINYINT. И сравнивать в запросе, соотв., число с числом.
Код: sql
1.
AND pay_transaction.action = 1

P.S. лучше не использовать зарезервированные слова в качестве названий таблиц/полей.
...
Рейтинг: 0 / 0
Отимизация таблицы
    #40123604
LentyMe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Gluck99,
В ENUM эти значения как пример , их не нужно учитывать
...
Рейтинг: 0 / 0
Отимизация таблицы
    #40123609
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если отформатировать запрос и поубирать лишнюю дрянь, то получается

Код: sql
1.
2.
3.
4.
5.
6.
7.
SELECT sum(pay_transaction.amount),
       sum(pay_transaction.bonus), 
       sum(pay_transaction.bonus)   
FROM pay_transaction   
WHERE pay_transaction.day BETWEEN "2021-12-20" AND "2021-12-27" 
  AND pay_transaction.action = '1' 
GROUP BY bet_transaction.account_id


И сразу выплывает вопрос - что за нафиг bet_transaction в выражении группировки?
И второй вопрос - нахрена две одинаковых суммы?

Но если предположить, что это очередная дрянь, то необходимый для быстрой работы запроса индекс как бы очевиден:
Код: sql
1.
CREATE INDEX idx ON pay_transaction (day, action, account_id, amount, bonus)


Возможно, первые два поля придётся поменять местами. Возможно, третье нужно поставить в начало. Это уже зависит от статистики реальных данных.
...
Рейтинг: 0 / 0
Отимизация таблицы
    #40123679
LentyMe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina,

К сожалению суть не в индексе, как мне кажется, а в настройках самой БД, так как даже по одиночному индексу date с условием between, select count(*) время запроса около 5c
...
Рейтинг: 0 / 0
Отимизация таблицы
    #40123682
SergiiW
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
LentyMe
Akina,

К сожалению суть не в индексе, как мне кажется, а в настройках самой БД, так как даже по одиночному индексу date с условием between, select count(*) время запроса около 5c
А Вы попробуйте и, думаю, почувствуете разницу. Правильные индексы - Бог SQL.

Akina
А какой смысл в индексах по полям amount и bonus? Они ведь не участвуют в отборе.
...
Рейтинг: 0 / 0
Отимизация таблицы
    #40123705
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SergiiW
А какой смысл в индексах по полям amount и bonus?

Зато получится покрывающий индекс, и для выполнения запроса к телу таблицы вообще обращаться не потребуется. На практике в половине случаев это сокращает время выполнения запроса приблизительно вдвое, в остальных случаях поменьше, но всё равно весьма прилично.
...
Рейтинг: 0 / 0
Отимизация таблицы
    #40123885
LentyMe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Другой запрос из этой же таблицы
Код: sql
1.
2.
3.
4.
5.
6.
SELECT
  SUM(pay_transaction.amount)
FROM `pay_transaction_softswiss` AS `bet_transaction`
WHERE `pay_transaction`.date BETWEEN "2021-12-20" AND "2021-12-27"
AND pay_transaction.action = 'complete'
GROUP BY pay_transaction.account_id



Время выполнения 15с!

Explain
{
"id": "1",
"select_type": "SIMPLE",
"table": "pay_transaction",
"partitions": "y2021m12",
"type": "index",

"key": "IDX_bet_test",
"key_len": "7",
"ref": "null",
"rows": "3866324",
"filtered": "33,33",
"Extra": "Using where; Using index"
}

Код: sql
1.
2.
ALTER TABLE pay_transaction
ADD INDEX IDX_pay_test (date, action, amount, account_id);



как видно индекс задан верно ?
...
Рейтинг: 0 / 0
Отимизация таблицы
    #40123960
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LentyMe
как видно индекс задан верно ?
Не совсем... как бы первые два поля поменять бы в выражении индекса местами, и два последние тоже.

"key_len": "7", ... "Extra": "Using where; Using index" говорит, что индекс используется, но не только как индекс (только первые 7 байт индексного выражения используются как индекс - видимо, только первые два поля), но и как компактная копия таблицы.
...
Рейтинг: 0 / 0
Отимизация таблицы
    #40123973
LentyMe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina,

Благодарю, реально помогло в этом запросе,
большая просьба, ткнуть носом меня , как раскрыть тайну порядка столбцов в индексе ?
...
Рейтинг: 0 / 0
Отимизация таблицы
    #40123985
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изучите порядок выполнения запросов.

Поля, используемые в условиях, обрабатываемых раньше, должны быть впереди. Среди условий одного этапа обработки впереди должны быть те, которые обеспечивают наибольшую селективность.
...
Рейтинг: 0 / 0
11 сообщений из 11, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Отимизация таблицы
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]