Два случая различны.
В первом случае в обоих столбцах необходимо искать одинаковое значение.Если у вас есть индекс из двух столбцов (u1, u2), то он может использоваться в столбце u1, поскольку его нельзя использовать в столбце u2.Если у вас есть два отдельных индекса для u1 и u2, вероятно, оба они будут использованы.Выбор зависит от статистики, основанной на количестве ожидаемых строк.Если ожидаемых возвращаемых строк мало, будет выбран поиск по индексу, если соответствующий индекс доступен.Если число высокое, сканирование предпочтительнее, либо таблица, либо индекс.
Во втором случае снова необходимо снова проверить оба столбца, но в каждом поиске есть два под-поиска, где второй под-поискбудет по результатам первого из-за условия AND.Здесь это имеет значение больше, и два индекса u1 и u2 помогут, так как любое поле, выбранное для поиска в первую очередь, будет иметь индекс.Выбор использования индекса аналогичен описанному выше.
В любом случае, однако, каждое ИЛИ будет вызывать еще 1 поиск или набор поисков.Таким образом, предлагаемое решение разбиения с использованием объединения не мешает больше, так как в таблице будет производиться поиск x раз, независимо от того, выбран ли 1 с помощью OR (s), или x выбирается с помощью объединения, и независимо от выбора индекса и типа поиска (поиск или сканирование).В результате, так как каждый выбор в объединении получает свою собственную часть плана выполнения, более вероятно, что будут использоваться индексы (один столбец) и, наконец, будут получены все наборы результатов строк из всех частей вокруг OR.Если вы не хотите копировать большой оператор выбора во многие объединения, вы можете получить значения первичного ключа, а затем выбрать их или использовать представление, чтобы убедиться, что большинство операторов находится в одном месте.
Наконец,если вы исключите опцию объединения, есть способ обмануть оптимизатор, чтобы он использовал один индекс.Создайте двойной индекс u1, u2 (или u2, u1 - любой столбец с большей мощностью будет первым) и измените свое утверждение так, чтобы все части ИЛИ использовали все столбцы:
... WHERE (user_1 = '$user_id' OR user_2 = '$user_id') ...
будет преобразовано в:
... WHERE ((user_1 = '$user_id' and user_2=user_2) OR (user_1=user_1 and user_2 = '$user_id')) ...
Таким образом, двойной индекс (u1, u2) будет использоваться всегда.Обратите внимание, что это не сработает, если столбцы обнуляются, и пропуск этого значения с помощью isnull или coalesce может привести к тому, что индекс не будет выбран.Однако он будет работать с отключенным значением ANSI.