Поиск данных, охватывающих множество таблиц - вопрос дизайна - PullRequest
2 голосов
/ 27 июля 2010

У меня есть структура около 10 таблиц.Эта структура отлично работает для ввода данных.Однако мне также необходимо предварительно выполнить сложные и быстрые поиски в этом наборе данных.Есть три подхода к этому:

  1. Соедините все эти таблицы в select.Это довольно медленно и, вероятно, не очень хороший подход.Если это актуально, база данных - Informix;Я смотрел на создание представлений, надеясь, что они будут более оптимизированы, но тестирование показывает, что выборки на представлениях даже медленнее, чем множество объединений.Может быть, есть какой-то способ создать таблицы предварительного объединения Informix и создать для них индексы, но из того, что я видел, это маловероятно.Я провел некоторое предварительное тестирование, и кажется, что представление даже медленнее, чем объединения, но, возможно, мне не хватает некоторых опций Informix.Оба соединения и представление работают медленнее, чем подход № 2:

  2. Одна синтетическая таблица, которая периодически обновляется.Это кажется правильным подходом, особенно потому, что поиск не должен проводиться по данным в реальном времени - на самом деле, я, вероятно, могу избежать ежедневного обновления синтетической таблицы.Размер данных будет около 500–1000 тыс. Строк.

  3. Memcached и аналогичные решения в памяти.На данный момент такой инфраструктуры нет, и, вероятно, это не оправдывает ее реализацию, однако я расскажу об этом, когда синтетическая таблица станет слишком медленной.Кроме того, существует множество параметров поиска, и даже первый запрос должен быть быстрым, поэтому при таком подходе все данные будут кэшироваться.Конечно, я, вероятно, кеширую все, что смогу, даже с подходами 1 и 2.

Мне бы хотелось, чтобы вы подумали об этом.Я пропускаю волшебную пулю?Что вы использовали в подобных ситуациях?

Ответы [ 7 ]

2 голосов
/ 27 июля 2010

Базы данных в памяти занимают время доступа к базе данных в миллисекундах и переводят их в время доступа в микросекундах.Это автоматическая торговая система или диспетчерская диспетчерская система 911 или система управления воздушным движением?Если нет, то вам будет трудно показать требование времени доступа в микросекундах.

Уолтер правильно сказал, когда сказал: "Как медленно, слишком медленно?"Четко определите ваши требования, это внутренний или внешний SLA?У вас есть требования?или это просто «кажется» слишком медленным.

Научитесь читать план выполнения и проверять план для вашего медленного запроса.Есть ли оценка кардинальности таким образом?Ожидается ли 1 строка, когда вы знаете, что есть 100 000 строк?Выполняет ли он полное сканирование таблицы, от которой вы ожидаете 1 строку?

Если запрос выглядит настолько эффективным, насколько это возможно, проследите его ... посмотрите, можете ли вы определить, есть ли какие-либо временные поглотители, которыеты не ожидаешь.Хорошо ли это делать в одиночку, но плохо под нагрузкой?Честно говоря, 10 таблиц с небольшим количеством данных для начала не должны быть слишком медленными.

Я думаю, что Гилберт переоценивает вашу проблему.При наличии не более 1 млн записей полноразмерная модель кажется излишней.По тону вашего вопроса это звучит так, будто вы просто пытаетесь ускорить запрос или три, а не создавать начало всей платформы BI.Если это так, посмотрите на план объяснения, посмотрите, сможете ли вы определить основные объемы работы, которые можно сократить с помощью предварительного расчета некоторых объединений (денормализация), создайте это новое представление материализации ... попробуйте запрос, еслибез улучшения, тогда отбросьте это и попробуйте что-нибудь другое ... не продолжайте наращивать неудачные попытки.

Теперь я вижу комментарий индустрии путешествий

Итак, у вас есть 2 класса комнаты, 30 двойных и20 синглов, и у вас есть 80 мест в самолете.Но в парном разряде можно добавить дополнительную кровать, чтобы у вас не хватило места перед тем, как заканчиваться номера.

Rooms Remaining
---------------
5 Single Remain
10 Doubles Remain

Seats Remaining
---------------
8 Plane seats

Так как есть один самолет и 2 типа номеров, вы просто будете декартово их вместе.

Package Type       Rooms      Seats      Packages Available
------------       ------     -----      ------------------
 Single              5           8             5
 Double              10          8             8

Обратите внимание, что доступные пакеты - это простой расчет НИЗКИЙ (Номера, Места)

В своем комментарии вы сказали

, даже если номера имеются, пакетофициально распроданы.

Package Type       Rooms      Seats      Packages Available
------------       ------     -----      ------------------
 Single              5           0             0
 Double              0           0             0

Итак, вот этот случай ... вы заполнили двухместные номера, и 5 из них тройные ... так что самолет полон, и есть 5 дополнительных одноместныхномера.Но наш НИЗКИЙ расчет подсчитывает, что нет доступных Одиночных пакетов.

Я близок?

2 голосов
/ 27 июля 2010

Вариант 1.

В зависимости от объема данных в ваших таблицах, 10 таблиц должны быть в состоянии объединиться за разумное время.Как медленно, слишком медленно для вас?

Вот две основные вещи, которые вы можете сделать, чтобы убедиться, что ваши запросы выполняются гладко.

Сначала убедитесь, что ваш дизайн логической таблицы действительно логичен.Плохой дизайн таблицы и плохой дизайн столбцов приводят к большому количеству ненужных замедлений в приложениях базы данных.Тот факт, что ввод данных работает хорошо, является довольно убедительным свидетельством того, что дизайн вашей таблицы довольно хорош.Ваш дизайн нормализован?Или несколько нормализовано?

Во-вторых, создайте правильные индексы.Правильные индексы могут сделать запрос в сто раз быстрее, в зависимости от обстоятельств.Чтобы построить правильные индексы, вам нужно немного узнать о том, как работают индексы, о запросе, который вы даете, об объеме данных и о стратегии, которую СУБД выбирает при выполнении запроса.

Вариант 2.

Это может быть вашим лучшим выбором.Узнайте немного о витринах данных или хранилищах данных.Вот как люди, работающие с базами данных, решают проблемы проектирования, связанные с одной схемой для ввода данных, другой схемой для запросов и процессом, позволяющим синхронизировать две схемы.

Здесь существует ряд проблем проектирования, а непопробуйте перечислить их, я просто хочу предложить вам получить доступ к витринам данных.

1 голос
/ 28 июля 2010

Как часто вам нужны критерии поиска по всем таблицам?

Один из способов повысить производительность - убедиться, что основной запрос адаптируется к критериям поиска, объединяя только необходимые таблицы и извлекая только значения первичного ключа из основной таблицы. Эти данные могут быть сохранены во временной таблице или в виде курсора прокрутки или возвращены клиенту.

Затем, когда вам нужно собрать информацию для отображения, вы используете (подготовленный) SELECT, который собирает именно те данные, которые вам нужны для нужных вам строк.

Преимущество этого состоит в том, что (для многих запросов) вы редко указываете условия для всех 10 таблиц, поэтому вам не нужно выполнять 10-стороннее соединение при обнаружении соответствующих записей. А однострочная операция - это все соединения ключей, поэтому поиск индексируется без сканирования.

Очевидно, вы можете манипулировать критериями; Вы можете выбрать все данные из первичной таблицы и все соответствующие значения из одной из вторичных таблиц (что всегда необходимо), но решите не выбирать какие-либо значения из других 8 таблиц (поскольку они не всегда отображаются в критерии поиска) или другие варианты в этом направлении.

Предполагается, что вы можете создавать динамический SQL, но это очень редко проблема.

1 голос
/ 27 июля 2010

Вариант 2 называется витриной данных или хранилищем данных. За счет дополнительного хранилища вы можете иметь оперативную базу данных и базу данных запросов.

Поскольку вы говорите, что существует множество параметров поиска, вы можете создавать таблицы запросов, используя звездообразную схему на основе параметров поиска.

1 голос
/ 27 июля 2010

Вы на правильном пути.

Для этого не существует волшебной пули, потому что ваши столы действительно разложены.В прошлом я делал что-то вроде своего варианта 2.

Допустим, у меня есть таблица счетов с идентификатором учетной записи в качестве PK.Я бы создал другую таблицу с именем AccountSearch, которая была бы связана в отношениях «многие к одному» со счетами.AccountSearch будет содержать набор строк и связанных с ними идентификаторов.

Если вам нужен нечеткий поиск, вы также можете манипулировать строками, используя NYIIS или Soundex (yuck) или просто удаляя пробелы.Вы также можете реализовать полнотекстовый поиск, но это часто излишне.

Account
-------
AccountID (PK)
Name
OwnerName

AccountSearch
-------------
SearchString (PK)
AccountID (PK)
0 голосов
/ 02 августа 2010

Объедините ваши 10 таблиц в одну временную таблицу. См .: Должен ли я денормализовать таблицы ссуд, закупок и продаж в одну таблицу?

0 голосов
/ 27 июля 2010

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

SELECT Name From Person
UNION SELECT Name FROM Company

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

...