Почему агрегатные функции SQL настолько медленнее, чем Python и Java (или OLAP Бедного Человека)

A ListIterator позволяет добавлять или удалять элементы в списке. Предположим, у вас есть список объектов Car:

List<Car> cars = ArrayList<>();
// add cars here...

for (ListIterator<Car> carIterator = cars.listIterator();  carIterator.hasNext(); )
{
   if (<some-condition>)
   { 
      carIterator().remove()
   }
   else if (<some-other-condition>)
   { 
      carIterator().add(aNewCar);
   }
}
14
задан Bill the Lizard 20 November 2011 в 13:46
поделиться

10 ответов

Пост-ГРЭС делает намного больше, чем это похоже (поддерживающий непротиворечивость данных для запуска!)

, Если значения не должны быть 100%-м пятном на, или если таблица редко обновляется, но Вы выполняете это вычисление часто, Вы могли бы хотеть изучить Осуществленные Представления для ускорения его.

(Примечание, я не использовал осуществленные представления в Пост-ГРЭС, они смотрят на небольшой hacky, но мог бы комплект своя ситуация).

Осуществленные Представления

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

я полагал бы, что 200 мс для чего-то вроде этого довольно хороши, быстрый тест на моем сервере оракула, той же структуре таблицы с приблизительно 500k строки и никакие индексы, занимает приблизительно 1 - 1.5 секунды, который является почти всем просто оракул, сосущий данные от диска.

реальный вопрос, 200 мс достаточно быстро?

--------------Больше--------------------

я интересовался решением этого использования, осуществило представления, так как я действительно никогда не играл с ними. Это находится в оракуле.

Первый я создал мВ, который обновляется каждую минуту.

create materialized view mv_so_x 
build immediate 
refresh complete 
START WITH SYSDATE NEXT SYSDATE + 1/24/60
 as select count(*),avg(a),avg(b),avg(c),avg(d) from so_x;

, В то время как его обновление, нет никаких строк, возвратился

SQL> select * from mv_so_x;

no rows selected

Elapsed: 00:00:00.00

, После того как оно обновляется, его НАМНОГО быстрее, чем выполнение необработанного запроса

SQL> select count(*),avg(a),avg(b),avg(c),avg(d) from so_x;

  COUNT(*)     AVG(A)     AVG(B)     AVG(C)     AVG(D)
---------- ---------- ---------- ---------- ----------
   1899459 7495.38839 22.2905454 5.00276131 2.13432836

Elapsed: 00:00:05.74
SQL> select * from mv_so_x;

  COUNT(*)     AVG(A)     AVG(B)     AVG(C)     AVG(D)
---------- ---------- ---------- ---------- ----------
   1899459 7495.38839 22.2905454 5.00276131 2.13432836

Elapsed: 00:00:00.00
SQL> 

, Если мы вставляем в базовую таблицу, результатом не является сразу видимое представление мВ.

SQL> insert into so_x values (1,2,3,4,5);

1 row created.

Elapsed: 00:00:00.00
SQL> commit;

Commit complete.

Elapsed: 00:00:00.00
SQL> select * from mv_so_x;

  COUNT(*)     AVG(A)     AVG(B)     AVG(C)     AVG(D)
---------- ---------- ---------- ---------- ----------
   1899459 7495.38839 22.2905454 5.00276131 2.13432836

Elapsed: 00:00:00.00
SQL> 

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

SQL> /

  COUNT(*)     AVG(A)     AVG(B)     AVG(C)     AVG(D)
---------- ---------- ---------- ---------- ----------
   1899460 7495.35823 22.2905352 5.00276078 2.17647059

Elapsed: 00:00:00.00
SQL> 

Это не идеально. для запуска, не в реальном времени, вставляет/обновляет, не будет сразу видимо. Кроме того, у Вас есть запрос, работающий для обновления мВ, нужен ли Вам он или не (это может быть мелодией к любому периоду времени, или по требованию). Но, это действительно показывает, насколько быстрее мВ может заставить его казаться конечному пользователю, если можно жить со значениями, которые не являются вполне до второго точного.

9
ответ дан 1 December 2019 в 07:13
поделиться

Я повторно протестировал с МЕХАНИЗМОМ определения MySQL = ПАМЯТЬ, и это не изменяет вещь (все еще 200 мс). Sqlite3 с помощью дб в оперативной памяти дает подобные синхронизации также (250 мс).

математика здесь корректные взгляды (по крайней мере, размер, как это - насколько большой sqlite дб :-)

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

Для разъяснения синхронизаций, код Java не читает из диска, делая его полностью несправедливым сравнением, если Пост-ГРЭС читает из диска и вычисляет сложный запрос, но это действительно помимо точки, DB должен быть достаточно умен загрузить маленькую таблицу в память и предварительно скомпилировать хранимую процедуру, по моему скромному мнению.

ОБНОВЛЕНИЕ (в ответ на первый комментарий ниже):

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

5
ответ дан 1 December 2019 в 07:13
поделиться

Я сказал бы, что Ваша тестовая схема не действительно полезна. Для выполнения запроса дб сервер дб проходит несколько шагов:

  1. анализируют SQL
  2. , обрабатывают план запросов, т.е. выбирают, который индексы использовать (если таковые имеются), оптимизируйте и т.д.
  3. , если индекс используется, ищите его указатели на фактические данные, затем перейдите к соответствующему местоположению в данных или
  4. , если никакой индекс не используется, просканируйте целая таблица для определения, какие строки необходимы
  5. , загружают данные из диска во временное местоположение (надо надеяться, но не обязательно, память)
  6. выполняют количество () и в среднем (), вычисления

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

Для получения большей информации о том, где Пост-ГРЭС проводит ее время я предложил бы следующие тесты:

  • Сравнивают время выполнения Вашего запроса к ВЫБОРУ без агрегирующихся функций (т.е. сократите шаг 5)
  • , Если Вы находите, что агрегирование приводит к значительному замедлению, попробуйте, если Python делает это быстрее, получая необработанные данные через простой ВЫБОР из сравнения.

Для ускорения запроса уменьшите доступ к диску сначала. Я сомневаюсь очень, что это - агрегирование, которое занимает время.

существует несколько способов сделать это:

  • Данные кэша (в памяти!) для последующего доступа, или через собственные возможности механизма дб или с инструментами как memcached
  • Уменьшают размер Ваших хранивших данных
  • , Оптимизируют использование индексов. Иногда это может означать пропускать индексное использование в целом (в конце концов, это - доступ к диску, также). Для MySQL я, кажется, помню, что рекомендуется пропустить индексы, если Вы предполагаете, что запрос выбирает больше чем 10% всех данных в таблице.
  • , Если Ваш запрос хорошо использует индексы, я знаю, что для баз данных MySQL он помогает поместить индексы и данные по отдельным физическим дискам. Однако я не знаю, применимо ли это для Пост-ГРЭС.
  • также могло бы быть более сложными проблемами, такими как свопинг строк к диску, если по некоторым причинам набор результатов не может быть полностью обработан в памяти. Но я оставил бы такое исследование, пока я не сталкиваюсь с серьезными проблемами производительности, которые я не могу найти другой способ решить, поскольку это требует знания о большом количестве небольших деталей под капотом в Вашем процессе.

Обновление:

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

15
ответ дан 1 December 2019 в 07:13
поделиться

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

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

Для предотвращения доступа к диску необходимо кэшировать целую таблицу в памяти, я могу вынудить Пост-ГРЭС сделать это? Я думаю, что это уже делает это, хотя, так как запрос выполняется во всего 200 мс после повторенных выполнений.

я могу сказать Пост-ГРЭС, что таблица только для чтения, таким образом, она может оптимизировать какой-либо код блокировки?

я думаю, что возможно оценить стоимость строительства запроса с пустой таблицей (диапазон синхронизаций от 20-60 мс)

, я все еще не вижу, почему тесты Java/Python недопустимы. Пост-ГРЭС просто не делает так намного большего количества работы (хотя я все еще не обратился к аспекту параллелизма, просто кэширование и запрашиваю конструкцию)

ОБНОВЛЕНИЕ: Я не думаю, что справедливо сравнить ВЫБОРЫ, как предложено путем получения по запросу 350,000 через драйвер и шаги сериализации в Python, чтобы выполнить агрегирование, ни даже опустить агрегирование как издержки в форматировании, и отображение трудно разделить от синхронизации. Если оба механизма воздействуют на в данных оперативной памяти, это должны быть яблоки к сравнению яблок, я не уверен, как гарантировать, что это уже происходит все же.

я не могу выяснить, как добавить комментарии, возможно, у меня нет достаточной репутации?

3
ответ дан 1 December 2019 в 07:13
поделиться

Я - парень MS-SQL сам, и мы использовали бы БИЛЬЯРД-АВТОМАТ DBCC для хранения таблицы кэшируемой, и статистика IO НАБОРА, чтобы видеть, что это читает из кэша и не диска.

я не могу найти, что что-либо на Пост-ГРЭС подражает БИЛЬЯРДУ-АВТОМАТУ, но , pg_buffercache, кажется, сообщает подробности относительно того, что находится в кэше - можно хотеть проверить, что, и видят, кэшируется ли таблица на самом деле.

А быстрая задняя часть вычисления конверта заставляет меня подозревать, что Вы - подкачка страниц от диска. Принятие Пост-ГРЭС использует 4-байтовые целые числа, у Вас есть (6 * 4) байты на строку, таким образом, Ваша таблица является минимумом (24 * 350,000) байты ~ 8.4 МБ. Принятие 40 МБ/с выдержало пропускную способность на Вашем жестком диске, Вы смотрите на правильные приблизительно 200 мс для чтения данных (которым, , как указано , должен быть то, где почти все время проводится).

, Если я не завинтил свою математику где-нибудь, я не вижу, как возможно, что Вы можете считать 8 МБ в свое приложение Java и обработать его во времена, которые Вы показываете - если тот файл уже не кэшируется или диском или Вашей ОС.

3
ответ дан 1 December 2019 в 07:13
поделиться

Я не думаю, что Ваши результаты - все это удивление - если что-либо, чем случается так, что Пост-ГРЭС так быстра.

Пост-ГРЭС запрашивает выполненный быстрее во второй раз, после того как это имело шанс кэшировать данные? Для ярмарки тест для Java и Python должен покрыть расходы на получение данных во-первых (идеально загружающий его от диска).

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

1
ответ дан 1 December 2019 в 07:13
поделиться

Вы используете TCP для доступа к Пост-ГРЭС? В этом случае Nagle смешивает с Вашей синхронизацией.

1
ответ дан 1 December 2019 в 07:13
поделиться

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

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

1
ответ дан 1 December 2019 в 07:13
поделиться

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

0
ответ дан 1 December 2019 в 07:13
поделиться

Спасибо за синхронизации Oracle это - вид материала, который я ищу (неутешительный, хотя :-)

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

я не думаю, что круговая задержка запроса должна быть очень высокой, поскольку я выполняю запросы на той же машине, которая выполняет Пост-ГРЭС, таким образом, она не может добавить много задержки?

я также сделал некоторых зарегистрировавшихся в размерах кэша, и кажется, что Пост-ГРЭС полагается на ОС для обработки кэширования, они конкретно упоминают BSD как идеальную ОС для этого, таким образом, я думающий Mac OS должен быть довольно умным о загрузке в память таблицы. Если кто-то не имеет более определенные параметрические усилители в виду, я думаю, что более определенное кэширование находится вне моего контроля.

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

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

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

0
ответ дан 1 December 2019 в 07:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: