Как создать индекс для массивных данных (mysql) - PullRequest
0 голосов
/ 07 октября 2011

Я сейчас оцениваю стратегию хранения каталогов поставщиков.В каталоге может быть несколько позиций от 100 до 0,25 млн.Каждый элемент может иметь несколько ошибок.приложение должно поддерживать просмотр элементов каталога

  • Группировать по типу ошибки, категории, производителю, поставщикам и т. д.
  • Просматривать элементы для любой группы, Должен иметь возможность сортировки и поиска понесколько столбцов (partid, имена, цена и т. д.)

Вопрос в том, когда мне нужно предоставить функциональность «Множественный поиск и сортировка и группа», как мне создать индекс.

Согласно mysql doc & blogs для индекса, создается впечатление, что создание индекса по отдельному столбцу будет использоваться не всеми запросами.

Создание многостолбцового индекса даже не характерно для моего случая.

Может быть 20-30 комбинаций поиска и сортировки групп.

Как мне масштабировать и как быстро выполнять поиск.

Ожидается обработка 50 миллионов записей данных.

В настоящее время оценивается 15 миллионов данных.

Предложения приветствуются.

CREATE TABLE CATALOG_ITEM
(
    AUTO_ID BIGINT PRIMARY KEY AUTO_INCREMENT,
    TENANT_ID VARCHAR(40) NOT NULL,
    CATALOG_ID VARCHAR(40) NOT NULL,
    CATALOG_VERSION INT NOT NULL,
    ITEM_ID VARCHAR(40) NOT NULL,
    VERSION INT NOT NULL,
    NAME VARCHAR(250) NOT NULL,
    DESCRIPTION VARCHAR(2000) NOT NULL,
    CURRENCY VARCHAR(5) NOT NULL,
    PRICE DOUBLE NOT NULL,
    UOM VARCHAR(10) NOT NULL,
    LEAD_TIME INT DEFAULT 0,
    SUPPLIER_ID VARCHAR(40) NOT NULL,
    SUPPLIER_NAME VARCHAR(100) NOT NULL,
    SUPPLIER_PART_ID VARCHAR(40) NOT NULL,
    MANUFACTURER_PART_ID VARCHAR(40),
    MANUFACTURER_NAME VARCHAR(100),
    CATEGORY_CODE VARCHAR(40) NOT NULL,
    CATEGORY_NAME VARCHAR(100) NOT NULL,
    SOURCE_TYPE INT DEFAULT 0,
    ACTIVE BOOLEAN,
    SUPPLIER_PRODUCT_URL VARCHAR(250),
    MANUFACTURER_PRODUCT_URL VARCHAR(250),
    IMAGE_URL VARCHAR(250),
    THUMBNAIL_URL VARCHAR(250),
    UNIQUE(TENANT_ID,ITEM_ID,VERSION),
    UNIQUE(TENANT_ID,CATALOG_ID,ITEM_ID)
);

CREATE TABLE CATALOG_ITEM_ERROR
(
    ITEM_REF BIGINT,
    FIELD VARCHAR(40) NOT NULL,
    ERROR_TYPE INT NOT NULL,
    ERROR_VALUE VARCHAR(2000)
);

1 Ответ

0 голосов
/ 07 октября 2011

Если вы решили сделать это исключительно в MySQL, то вам следует создавать индексы, которые будут работать для всех ваших запросов.Можно иметь 20 или 30 индексов, если вы сортируете 20-30 различных запросов.Но вы можете, вероятно, сделать это с гораздо меньшими показателями, чем это.

Вам также необходимо спланировать, как будут поддерживаться эти индексы.Я предполагаю, потому что это для каталогов поставщиков, что данные не будут сильно меняться.В этом случае простое создание всех необходимых вам индексов должно хорошо работать.Если строки данных будут часто редактироваться или вставляться в режиме реального времени, то вы должны учитывать это при индексировании - тогда наличие 20 или 30 индексов может быть не очень хорошей идеей (поскольку MySQL будет постоянно вынужден обновлять их все),Вы также должны рассмотреть, какой механизм хранения MySQL использовать.Если ваши данные никогда не меняются, MyISAM (механизм по умолчанию, в основном быстрые плоские файлы) является хорошим выбором.Если он сильно меняется, то вы должны использовать InnoDB, чтобы получить блокировку на уровне строк.InnoDB также позволит вам определить кластеризованный индекс, который является специальным индексом, который контролирует порядок вещей, хранящихся на диске.Таким образом, если бы у вас был один конкретный запрос, который выполняется 99% времени, вы могли бы создать для него кластерный индекс, и все данные уже были бы в правильном порядке на диске и возвращали бы супер супер быстро.Но каждая вставка или обновление данных приведет к переупорядочению всей таблицы на диске, что не очень быстро для большого количества данных.Вы никогда не использовали бы его, если бы данные вообще часто менялись, и вам, возможно, придется пакетно загружать обновления данных (например, новые версии миллиона строк поставщика).Опять же, все сводится к тому, будете ли вы обновлять его никогда, время от времени или постоянно в режиме реального времени.

Наконец, вам следует рассмотреть альтернативные способы, чем делать это в MySQL.Сейчас существует множество действительно хороших поисковых продуктов, таких как Apache Solr или Sphinx (упомянутых в комментарии выше), которые могут значительно облегчить вашу жизнь при кодировании самих поисковых интерфейсов.Вы можете индексировать каталоги в одном из них, а затем использовать их для предоставления действительно потрясающих функций поиска, таких как полнотекстовый и / или граненый поиск.Это похоже на частную поисковую систему Google, которая индексирует ваши материалы, это хороший способ описать, как они работают.Для написания кода для взаимодействия с поисковым сервером требуется время, но вы, скорее всего, сэкономите это время, не прибегая к написанию и обдумыванию проблемы индексирования и других проблем, о которых я упоминал выше.

Если вы это сделаетепросто создайте все индексы, узнайте, как использовать команду EXPLAIN в MySQL.Это позволит вам увидеть, каким будет план MySQL для выполнения запроса.Вы можете создать индексы, затем повторно запустить EXPLAIN для ваших запросов и посмотреть, как MySQL собирается их использовать.Таким образом, вы можете быть уверены, что у каждого из ваших методов запросов есть индексы, поддерживающие его, и не будете использовать сканирование всей таблицы данных для поиска.С таким количеством строк, о котором вы говорите, каждый запрос ДОЛЖЕН иметь возможность использовать индексы для поиска своих данных.Если вы поймете это правильно, все будет хорошо.

...