Вопрос

  1. Теперь у меня есть таблица, содержащая более 43 миллионов записей.Для выполнения SELECT, я обычно выбираю записи с одним и тем же полем, скажем A.Будет ли эффективнее разделить таблицу на несколько таблиц по разным A и сохранить в базе данных?Сколько я могу получить?

  2. У меня есть одна таблица с именем entry: {entryid (PK), B}, содержащая 6 тысяч записей, и несколько других таблиц с аналогичной структурой T1: {id(PK), entryid, C, ...}, содержащий более миллионов записей.Имеют ли следующие два процесса одинаковую эффективность?

    SELECT id FROM T1, entry WHERE T1.entryid = entry.entryid AND entry.B = XXX

и

SELECT entryid FROM entry WHERE B = XXX
//format a string S as (entryid1, entryid2, ... )
//then run
SELECT id FROM T1 WHERE entryid IN S
Это было полезно?

Решение

В данном случае я сначала отвечу на ваш второй вопрос.

Существует способ объединить запросы, чтобы они вели себя как один и делали это эффективно.

Ваш первый метод - это запрос, который ведет себя следующим образом

  • ОБЪЕДИНЕНИЕ T1 и entry Автор: entryid формирование гигантской временной таблицы
  • Пройдите по временной таблице, чтобы обработать предложение WHERE

Ваш второй метод - это, по сути, два запроса

  • Поиск entryid где B - некоторое значение XXX
  • Скомпилировать все entryid значения в строке
  • Выполнить запрос, используя WHERE entryid IN
  • Объединенный список на месте в неиндексированной временной таблице
  • Декартово СОЕДИНЕНИЕ обратно с T1, чтобы увидеть, какие значения совпадают

В обоих случаях вы все равно должны сформировать временную таблицу entryid ценности

Что вам нужно сделать, так это реорганизовать выполнение запроса, также известного как .рефакторинг.

Вот ваш первый запрос, полностью переработанный:

SELECT
    A.entryid
FROM
    (SELECT entryid id FROM entry WHERE B = XXX) A
    LEFT JOIN T1 USING (id)
;

Это представляет ваш запрос, но он выполняет две вещи

  1. Сначала он объединяет в списке идентификаторы входа, используя предложение WHERE
  2. Он выполняет СОЕДИНЕНИЕ на основе длины подзапроса A

Эта реорганизация должна ускорить обработку без дополнительных изменений таблицы.

Однако, поскольку подзапрос A получает entryid значения, основанные на значении B, у вас должен быть индекс, который поможет быстро их округлить.Пожалуйста, создайте этот индекс:

ALTER TABLE entry ADD INDEX B_entryid_ndx (B,entryid);

Используя этот новый реорганизованный запрос и создавая этот дополнительный индекс, это происходит настолько быстро, насколько это возможно, поскольку рефакторинг заставляет WHERE происходить до объединения.

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

MySQL поддерживает две парадигмы секционирования

С механизмом хранения данных СЛИЯНИЯ нет длинного пути миграции.Отображение происходит за 2 секунды.Обслуживание каждой отдельной таблицы может повлиять на любой запрос к механизму СЛИЯНИЯ, если нет первичного ключа для уникальной идентификации одной таблицы MyISAM из другой таблицы MyISAM.

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

В любом случае, должна быть создана хорошо продуманная схема индексации.Почему?Предложения запроса WHERE, ORDER BY и GROUP BY должны определять, какие индексы действительно необходимы для поддержки запроса.

Другие советы

Я бы рассматривал возможность использования разбиения таблиц на разделы.Вы не упоминаете версию mysql или типы движков хранения.Вот ссылка на документ:

http://dev.mysql.com/doc/refman/5.6/en/partitioning.html

для 5.6

Лицензировано под: CC-BY-SA с атрибуция
Не связан с dba.stackexchange
scroll top