Оптимизировать базу данных для поиска (и интерполяции поисковых значений) - PullRequest
1 голос
/ 28 августа 2009

У меня есть сравнительно большие таблицы базы данных (чуть меньше миллиона строк), которые имеют такое отображение:

(int, int, int, int) ----> (float, float)

Не все возможные комбинации int сопоставляются с плавающей парой.

На этом мои знания о дизайне базы данных заканчиваются:

  1. Размер базы данных меня не беспокоит, но время запроса. Стоит ли беспокоиться об оптимизации базы данных для поиска? Было бы достаточно, если бы я только что сделал один запрос к приведенной выше таблице, или я должен использовать какую-то схему для оптимизации способа хранения информации?

  2. Мне также нужно пойти другим путем, но проблема здесь в том, что мне нужно будет найти ближайшее значение моей пары (float, float), которое соответствует моим параметрам, поэтому для этого потребуется интерполяция переданного float ценности. Я собирался искать ближайшее значение первого числа, затем второго числа, затем совпадения в таблице. Опять же, есть ли что-нибудь, что я могу сделать с моим столом, чтобы сделать его лучше для такого поиска?

Спасибо,

Ответы [ 2 ]

2 голосов
/ 28 августа 2009

Из-за длинного размера сообщения, резюме

  1. Проверка Пространственное расширение MySQL
  2. Поскольку последовательности вашего int имеют значение, вы можете комбинировать или хешировать их в ключ, который MySQL может индексировать и искать быстрее, сохраняя целые числа для рефакторинга ключ, когда они меняются.
  3. Вы находитесь в прекрасном положении для распределения / распараллеливания / подмножества с использованием первого
    целое число как ключ к какому-то механизму распределения, а второе и т. д.
  4. Примеры, представленные ниже, немного мешают, возможно, вызывая 2 ^ 32 базы данных каждая с 2 ^ 32 таблицами, затем 2 ^ 32 строк. Они всего лишь примеры использования большого количества пространство для увеличения скорости.
  5. Я не эксперт по БД.

Выглядит как инъективное отображение значений с плавающей точкой в ​​целочисленные последовательности.

Я бы пошел на:

tbl:
varchar my_ints; float; int a, int b, int c, ...

А затем интерполировать целые числа в строку:

"abcde", например, "1928 9384 2993 4884" (игнорируя пробелы)

А затем позвольте MySQL выполнить поиск по строковому индексу.

Или, как другие предлагали, исследовать Пространственные расширения MySQL . Если они не применяются, вот некоторые идеи, которые могут представлять интерес:

Я бы держал все данные в одной таблице (или объединенной таблице). Не иметь внешних ключей для поплавков или чего-то в этом роде. Затраты на объединение не стоят того, и вы не беспокоитесь о размере. (Я не думаю, что вы бы разбили стол, просто сказав: S)

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

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

Доступ к базе данных работает по уровням. Оптимизируйте свои поиски (может помочь отладчик SQL-запросов, например, стендовая версия MySQL), а затем убедитесь, что вы не запрашиваете больше, чем нужно.

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

int_tbl = { int_hash_index, int_a, int_b, int_c, float_value }

Тогда вы сможете увидеть общее улучшение, переведя элемент поиска (в данном случае целые числа) в одно более доступное для поиска количество.

Итак, если вы говорите:

SELECT float_value FROM int_tbl WHERE int_a=x AND int_b=y ...

Тогда вы можете превратить это в:

SELECT float_value FROM int_tbl WHERE int_hash_index=pre_computed_value

При условии, что:

  1. Хеш индексируется и представляет собой идеальное отображение между целыми числами.
  2. Хеш можно использовать в качестве первичного ключа, что позволяет удалять дубликаты
  3. Улучшена производительность перечисления кортежей.

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

Точка 3 кажется очевидной, но вам нужно протестировать и протестировать.

Также в зависимости от вычисления f (a, b, c, d) -> float, например:

f() = (a*b*c*d)*pi

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

Просто некоторые идеи, я не эксперт.

Редактировать из-за информации GPS Сначала проверьте пространственные расширения mysql ...

ниже вы сказали, что это данные GPS. В этом случае целые числа относятся друг к другу, я полагаю. И их последовательность имеет значение ... вы можете склеить их в двоичное значение, например:

tbl_key_blob = [int_a_bits int_b_bits int_c_bits]

И используйте это как свой ключ. Однако я не знаю, насколько эффективна индексация произвольных двоичных значений в MySQL. Я думаю, что дерево поиска было бы весьма эффективным.

Вы также можете иметь отдельные таблицы, если a в (a, b, c, d) является позиционным. Так

int_map_1234_tbl = { int_b, int_c, int_d, float }

Где 1234 равно int_a = 1234, поэтому, если у вас есть запрос:

SELECT * FROM int_tbl WHERE a=x AND b=y ...

Вы можете выбрать таблицу на основе интерполяции:

SELECT * FROM int_map_[a's value here]_tbl WHERE b=y AND c=z ...

конечно, вы можете сделать это до степени n-1 и в итоге:

SELECT * FROM int_map_[c's value here]_tbl WHERE d=d';

Но вам потребуется эффективное разрешение таблиц, и это миссия с точки зрения размера и производительности, поскольку вы получите ОЧЕНЬ БОЛЬШИЕ индексы таблиц.

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

database_[a's value here] -> table_[b's value here]_tbl -> SELECT * FROM that WHERE c=x ...

Таким образом, вы вставляете 'a' в имя базы данных, 'b' в таблицу и ищите на C, а затем D. Всякая чушь на самом деле, пока вы не попробуете что-то и сравните с реальными запросами.

Вы находитесь в действительно прекрасном положении для распределения запросов по многим базам данных, подумайте

node_[a's value].mydbcluster.com->database_[b's value]->table[c's] ...

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

Преимущество этого состоит в том, что, если какой-либо из следующих шагов завершится неудачей:

  1. подключиться к машине с надписью 'a'
  2. подключиться к базе данных с 'b' в ней
  3. выберите таблицу с 'c' и позже

тогда вы знаете, что комбинация (a, b, c, d, ...,) не существует. И ты все равно должен выполнить эти шаги.

Возможно, это излишне, потому что вы можете получить множество таблиц / баз данных , если вы не получите кластеры чисел.

Я не эксперт по базам данных, и когда кто-то прибудет, у меня / нее будут комментарии к нему;) И так далее.

удачи

0 голосов
/ 28 августа 2009

Как группы int отображаются на пары с плавающей точкой? Это помогло бы узнать, как выполняется сопоставление.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...