MySQL, не используя индекс с СОЕДИНЕНИЕМ, ГДЕ и ПОРЯДОК

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

Большинство файловых систем настроено для использования размеров блока 4 096 или 8192. В теории при конфигурировании размера буфера, таким образом, Вы читаете несколько байтов больше, чем дисковый блок, операции с файловой системой могут быть чрезвычайно неэффективными (т.е. если бы Вы настроили свой буфер для чтения 4 100 байтов за один раз, каждое чтение потребовало бы 2 чтений блока файловой системой). Если блоки уже находятся в кэше, то Вы волнуете оплату цены RAM-> задержка кэша L3/L2. Если Вы неудачны, и блоки еще не находятся в кэше, Вы платят цену на диск-> задержка RAM также.

Поэтому Вы рассматриваете большинство буферов, измеренных как питание 2, и обычно больше, чем (или равный) размер дискового блока. Это означает, что одно из Ваших потоковых чтений могло привести к нескольким чтениям дискового блока - но те чтения будут всегда использовать полный блок - никакие потраченные впустую чтения.

Теперь, это смещается вполне немного в типичном сценарии потоковой передачи, потому что блок, который читается из диска, собирается все еще быть в памяти при ударе следующего чтения (мы делаем последовательные чтения здесь, в конце концов) - таким образом, Вы волнуете оплату RAM-> цена задержки кэша L3/L2 на следующее чтение, но не диск-> задержка RAM. С точки зрения порядка величины диск-> задержка RAM является столь медленной, что это в значительной степени затопляет любую другую задержку, с которой Вы могли бы иметь дело.

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

существуют тонна из условий и исключений здесь - сложности системы на самом деле вполне колеблются (просто получение дескриптора на L3->, кэш L2 передает, ум bogglingly комплекс, и это изменяется с каждым типом ЦП).

Это приводит к ответу 'реального мира': Если Ваше приложение похоже на 99% там, установите размер кэша на 8 192 и движение (еще лучше, предпочтите инкапсуляцию производительности и используйте BufferedInputStream для сокрытия деталей). Если Вы находитесь в 1% приложений, которые очень зависят от дисковой пропускной способности, обрабатывают Вашу реализацию, таким образом, можно выгрузить различные дисковые стратегии взаимодействия, и обеспечивать кнопки и наборы, чтобы позволить пользователям тестировать и оптимизировать (или придумывать некоторых сам оптимизация системы).

7
задан pikachu 23 October 2012 в 15:04
поделиться

2 ответа

Когда я пытаюсь воспроизвести этот запрос с помощью ваших скриптов:

SELECT  A.a, A.b, B.c
FROM    A
JOIN    B
ON      A.b = B.b
WHERE   a = 44
ORDER BY
        c

, он завершается за 0,0043 секунды (мгновенно), возвращает 930 строк и дает следующий план:

1, 'SIMPLE', 'A', 'ref', 'PRIMARY', 'PRIMARY', '4', 'const', 1610, 'Using index; Using temporary; Using filesort'
1, 'SIMPLE', 'B', 'eq_ref', 'PRIMARY', 'PRIMARY', '4', 'test.A.b', 1, ''

Это довольно эффективно для такого запроса.

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

См. эту статью в моем блоге для более подробных объяснений:

Если вы ожидаете, что ваш запрос вернет несколько записей, вы должны использовать индекс для A для фильтрации и последующей сортировки с использованием файловой сортировки (как в запросе выше).

Если вы ожидаете, что он вернет много записей (и LIMIT их), вам нужно использовать индекс для сортировки и фильтрации:

CREATE INDEX ix_a_b ON a (b);
CREATE INDEX ix_b_c ON b (c)

SELECT  *
FROM    B FORCE INDEX (ix_b_c)
JOIN    A
ON      A.b = B.b
ORDER BY
        b.c
LIMIT 10;

1, 'SIMPLE', 'B', 'index', '', 'ix_b_c', '4', '', 2, 'Using index'
1, 'SIMPLE', 'A', 'ref', 'ix_a_b', 'ix_a_b', '4', 'test.B.b', 4, 'Using index'
9
ответ дан 7 December 2019 в 01:24
поделиться

выберите Aa, Ab, Bc из A, соединение B на Ab = Bb, где a = 44, порядок по c;

Если вы задаете псевдоним столбцов, это поможет? Пример:

 SELECT 
 T1.a AS colA, 
 T2.b AS colB, 
 T2.c AS colC 
 FROM A AS T1 
 JOIN B AS T2 
 ON (T1.b = T2.b) 
 WHERE 
 T1.a = 44 
 ORDER BY colC;

Я внес только следующие изменения:

  • Я заключил условия соединения в скобки
  • Условия соединения и где условия основаны на столбцах таблицы
  • Условие ORDER BY основано на столбце результирующей таблицы
  • Я присвоил столбцам таблицы результатов и запрашиваемым таблицам псевдонимы, чтобы (надеюсь) сделать более понятным, когда я использовал тот или иной (и более понятным для сервера. Вы пренебрегаете ссылками на столбцы в двух местах в исходном тексте). query).

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

1
ответ дан 7 December 2019 в 01:24
поделиться
Другие вопросы по тегам:

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