Я читаю Hadoop: окончательный путеводитель Тома Уайта. В главе 13.6 «HBase vs RDMS» он сказал, что если у вас много данных, даже простые запросы, такие как получение 10 последних элементов, чрезвычайно дороги, и им пришлось переписать их с помощью python и PL/SQL.Являются ли RDBMS плохой, как описано в Hadoop: окончательное руководство?
Он дает следующий запрос в качестве примера:
SELECT id, stamp, type FROM streams
WHERE type IN ('type1','type2','type3','type4',...,'typeN')
ORDER BY stamp DESC LIMIT 10 OFFSET 0;
И говорит: «запрос RDBMS планировщик обрабатывает этот запрос, следующим образом:
MERGE (
SELECT id, stamp, type FROM streams
WHERE type = 'type1' ORDER BY stamp DESC,
...,
SELECT id, stamp, type FROM streams
WHERE type = 'typeK' ORDER BY stamp DESC
) ORDER BY stamp DESC LIMIT 10 OFFSET 0;
Проблема здесь состоит в том, что мы после только 10 лучших идентификаторов, но запрос планировщик фактически реализует весь слияние, а затем лимит на конец. .... Мы фактически зашли так далеко, как , чтобы написать пользовательский сценарий PL/Python , который выполнил хапсорт. ... В почти во всех случаях это обогнал родной реализации SQL и стратегия планировщика запроса ...
Ожидаемой perforamnce и expermiental результатов
Я не мог себе представить набор данных что вызовет такие проблемы, которые вы должны написать PL/Python, чтобы сделать такой простой запрос права. Поэтому я немного поработал над этой проблемой и придумал следующие наблюдения:
Производительность такого запроса ограничена O (KlogN). Потому что он может быть переведен так что-то выглядит следующим образом:
SELECT * FROM (
SELECT id, stamp, type FROM streams
WHERE type = 'type1' ORDER BY stamp DESC LIMIT 10,
UNION
...,
SELECT id, stamp, type FROM streams
WHERE type = 'typeK' ORDER BY stamp DESC LIMIT 10
) t ORDER BY stamp DESC LIMIT 10;
(обратите внимание на «LIMIT 10» при каждом запросе КСТАТИ я знаю, что я не могу ограничить и союзы порядка, но я уже раздел упаковку выбирает. для удобства чтения)
Каждый подзапрос должен работать так же быстро, как поиск правильной позиции в индексе O (logN) и возврат 10 элементов. Если мы повторим, что K раз мы получаем O (KlogN).
И даже если планировщик запросов настолько плох, что не может оптимизировать первый запрос, мы всегда можем перевести его на запрос с помощью союзов и получить желаемую производительность без записи чего-либо в файле pl/python.
Чтобы удвоить мои расчеты, я выполнил запросы выше одного postgresql, заполненного 9 000 000 тестовых записей. Результаты подтвердили мои ожидания, что оба запроса были довольно быстрыми 100 мс для первого запроса и 300 мс для второго (одно с объединениями).
Так что если запрос выполняется в 100 мс для 9 000 000 (logn = 23) записей, то для 9 000 000 000 (logn = 33) записей он должен работать в 140 мс.
Вопросы
- вы видите какие-либо недостатки в приведенных рассуждениях?
- Можете ли вы представить набор данных, где вам нужно будет переписать такой запрос, как указано выше в pl/python?
- Вы видите какую-либо ситуацию, когда такой запрос не будет работать в O (K log n)?
Нет, это не так. Какая база данных запрашивает полную таблицу один раз для каждого элемента в фильтре поля, объединяет все записи вместе, заказывает их, а затем делает ограничение в конце? – MkV 2010-11-27 00:41:01