Oracle несколько против одного индекса столбца - PullRequest
2 голосов
/ 20 января 2020

Представьте, что у меня есть таблица со следующими столбцами:

  1. Столбец: A (число (10)) (PK)
  2. Столбец B ( numer (10))
  3. Столбец: C (numer (10))

    CREATE TABLE schema_name.table_name (
    column_a number(10) primary_key,
    column_b number(10) ,
    column_a number(10)
    );
    

Столбец A - это мой PK.

Представьте, что у моего приложения теперь есть поток, который запрашивает B и C. Примерно так:

SELECT * FROM SCHEMA.TABLE WHERE B=30 AND C=99

Если я создам индекс только с использованием столбца B , это уже улучшит мой запрос, верно?

Стратегия, лежащая в основе этого запроса, выиграет от индекса по столбцу B?

Q1 - Если так, зачем мне создавать индекс с этими двумя столбцами?

Q2 - Если я решу создать индекс с B и C, если я сделаю запрос на выбор только B , повлияет ли этот индекс на индекс?

Ответы [ 4 ]

1 голос
/ 20 января 2020

Несмотря на то, что на этот вопрос уже дан ответ и один ответ уже принят, я просто добавлю еще немного информации: -)

Индекс - это предложение для СУБД, которое оно может использовать для доступа к данным. быстрее в некоторых ситуациях. Использует ли он на самом деле индекс, - это решение, принятое СУБД.

Oracle имеет встроенный оптимизатор, который просматривает запрос и пытается найти наилучший план выполнения, чтобы получить результаты, к которым вы стремитесь.

Предположим, что 90% всех строк имеют B = 30 AND C = 99. Зачем тогда Oracle кропотливо проходить по индексу только для того, чтобы наконец получить доступ почти ко всем строкам таблицы? Таким образом, даже с индексом в обоих столбцах Oracle может решить вообще не использовать индекс и даже выполнить запрос быстрее из-за решения по индексу.

Теперь к вопросам:

Если я создаю индекс только с использованием столбца B, это уже улучшит мой запрос, верно?

Может. Если Oracle считает, что B = 30 уменьшает количество строк, которые ему придется прочесть из таблицы, то это будет.

Если это так, зачем мне создавать индекс с этими двумя столбцами?

Если комбинация B = 30 AND C = 99 ограничивает строки для дальнейшего чтения из таблицы, лучше использовать этот индекс вместо этого.

Если я решил создать индекс с B и C, если я запрашиваю выбор только B, будет ли индекс затронут этот индекс?

Если индекс находится на (B, C), т.е. сначала B, то Oracle может оказаться полезным, да. В крайнем случае, когда в таблице есть только два столбца, это будет даже покрывающий индекс (т. Е. Содержащий все столбцы, к которым обращаются в запросе), и СУБД не должна будет читать какую-либо строку таблицы, так как вся информация уже в самом индексе. Если индекс равен (C, B), т. Е. Сначала C, маловероятно, что индекс будет использоваться. В некоторых крайних случаях Oracle может сделать это, однако.

1 голос
/ 20 января 2020

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

Внутри SQL (Oracle, Postgre, Ms Sql, et c.) Первичный ключ используется как минимум для две цели:

  • Упорядочение строк (например, если PK увеличивается только тогда, все значения будут добавлены)
  • Ссылка на строку. Это означает, что если у вас есть какой-либо дополнительный индекс, он будет содержать целое PK, чтобы иметь возможность переходить с дополнительного индекса на другие строки.

Если я создаю индекс только с использованием столбца B, это уже улучшит мой запрос, верно? Стратегия, лежащая в основе этого запроса, выиграет от индекса в столбце B?

Это зависит. Если ваш стол слишком мал, Oracle может выполнить его полное сканирование. Для большой таблицы Oracle можно (и будет делать в обычном сценарии) использовать индекс для столбца B, а затем выполните Range Scan . В этом случае Oracle проверьте все значения с B = 30. Следовательно, если вы можете использовать только одну строку с B = 30, вы сможете добиться хорошей производительности. Если у вас есть миллионы таких строк, Oracle потребуется выполнить миллион операций чтения. Oracle может получить эту информацию через statisti c.

Q1 - Если так, почему я должен создавать индекс с этими двумя столбцами?

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

Однако если в вашей таблице есть другие столбцы, реальный план выполнения будет включать доступ к PK (для получения других строк).

Если бы я решил создать индекс с B и C, если я запросил выбор только B, повлияет ли на этот индекс индекс?

Да. Пожалуйста, проверьте детали здесь . Если в индексе несколько столбцов, Oracle отсортирует их в соответствии с порядком столбцов. Например, если вы создадите индекс со столбцами B, C, тогда Oracle сможет использовать его для извлечения значений типа «B = 30», например, когда вы ограничиваете только B.

1 голос
/ 20 января 2020

Простые ответы на ваши вопросы.

Для этого запроса:

SELECT *
FROM SCHEMA.TABLE
WHERE B = 30 AND C = 99;

Оптимальный индекс: либо (B, C), либо (C, B). Порядок имеет значение, потому что два сравнения: =.

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

Если у вас есть индекс на (B, C), то это можно использовать для запроса на WHERE B = 30. Oracle также реализует оптимизацию с пропуском сканирования, поэтому возможно, что индекс также можно будет использовать для WHERE C = 99 - но, вероятно, это не так.

Я думаю, что документация для MySQL имеет хорошее введение в многостолбцовые индексы. Он не покрывает skip-scan, но в остальном вполне применим к Oracle.

0 голосов
/ 20 января 2020

Ну, все это зависит .

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

Если таблица огромная , то это зависит от селективности столбца. Нет гарантии, что Oracle когда-либо будет использовать этот индекс. Если оптимизатор решает (на основании имеющейся у него информации - не забывайте регулярно собирать статистику!), Что индекс не следует использовать, то вы создали его напрасно (хотя вы можете использовать подсказку, но - если вы не знаете, что ты делаешь, не делай этого).

Как ты узнаешь, что происходит? См. План объяснения.

Но, вообще говоря, да - индексы помогают.


В1. Если да, то зачем мне создавать индекс с этими двумя столбцами?

Какие «два столбца»? A? Если это столбец первичного ключа, Oracle автоматически создает индекс, вам не нужно этого делать.


Q2 - Если я решу создать индекс с B и C, если я сделаю запрос на выбор только B, будет ли индекс затронут этот индекс?

Если вы говорите о составном индексе (содержащем столбцы B и C соответственно), и если в запросе используется столбец B, тогда yes - index будет (ОК, может использоваться ). Но если в запросе используется только столбец C, этот индекс будет полностью бесполезным.

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