Как получить доступ к 50 записям Milion, используя кодировку «ИЛИ» в MySQL 5.7 - PullRequest
0 голосов
/ 12 октября 2019

У меня 300 миллионов данных в одном разделе, и теперь я хотел бы отфильтровать эту запись, используя условие или условие для 2 столбца (индекс). это возможно?

CREATE TABLE `temp_bulk_tesing` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `request_account` INT(11) NOT NULL DEFAULT '0',
    `responce_account` INT(11) NOT NULL DEFAULT '0',
    `creatition_date` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (`id`),
    INDEX `request_account` (`request_account`),
    INDEX `responce_account` (`responce_account`),
    INDEX `creatition_date` (`creatition_date`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
AUTO_INCREMENT=16371
; 
CREATE TABLE `org_account` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `name` VARCHAR(50) NULL DEFAULT NULL,
    PRIMARY KEY (`id`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
;
select count(temp_bulk_tesing.id) from temp_bulk_tesing
inner join org_account
on (temp_bulk_tesing.request_account=org_account.id
or temp_bulk_tesing.responce_account=org_account.id)
and temp_bulk_tesing.creatition_date >='2019-10-10 22:22:18'
and temp_bulk_tesing.creatition_date <= '2019-10-13 22:22:18'

это занимает слишком много времени. как мы можем оптимизировать это?

Разделы также существуют в исходной таблице, но проблема в том, что мы получаем 300 миллионов записей за 1 день.

Ответы [ 2 ]

0 голосов
/ 12 октября 2019

Хранимая процедура может быть немного сложна для реализации, но она того стоит.

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

create temporary table tmp_temp_bulk_tesing
select * from temp_bulk_tesing where creatition_date between '2019-10-10 22:22:18'and 
'2019-10-13 22:22:18';

Добавьте индекс всделайте вещи еще быстрее

alter table tmp_temp_bulk_tesing add INDEX ttbt (id);

Затем выполните объединение

select count(temp_bulk_tesing.id) from tmp_temp_bulk_tesing ttbt
inner join org_account oa
on (ttbt.request_account=oa.id or ttbt.responce_account=oa.id)

Объединение ОЧЕНЬ тяжело для базы данных, и, выделив правильные данные, вы можете переходить от часов к секундам или даже дробисекунды, чтобы его обработать.

Еще один прием, который может помочь, - вместо использования

 and temp_bulk_tesing.creatition_date >='2019-10-10 22:22:18'
 and temp_bulk_tesing.creatition_date <= '2019-10-13 22:22:18'

- сначала отдельно получить максимальный и минимальный идентификаторы из базы данных и включить их взапрос.

 select max(id), min(id) from temp_bulk_tesing where creatition_date between '2019-10-10 22:22:18' and '2019-10-13 22:22:18'

и затем используйте эти идентификаторы в запросе. index в int должен быть быстрее, чем index для datetime, а id должен быть в порядке, чтобы сделать его еще проще.

Это не так эффективно, как временные таблицы, но может быть достаточно для вас.

0 голосов
/ 12 октября 2019

Вы можете попробовать UNION ALL:

SELECT COUNT(*)
FROM (
  select temp_bulk_tesing.id
  from temp_bulk_tesing
  join org_account
    on temp_bulk_tesing.request_account=org_account.id
   and temp_bulk_tesing.creatition_date BETWEEN '2019-10-10 22:22:18'AND'2019-10-13 22:22:18'
  union all
  select temp_bulk_tesing.id
  from temp_bulk_tesing
  join org_account
    on temp_bulk_tesing.responce_account=org_account.id
   and temp_bulk_tesing.creatition_date BETWEEN '2019-10-10 22:22:18'AND'2019-10-13 22:22:18'
) sub
...