May 4th, 2007

OR vs UNION

Задача: достать из базы одним запросом корневые объекты и все объекты текущего треда, чтобы потом построить из них меню сайта и дублирующую навигацию.

Решение «в лоб»:
SELECT
	object_id AS id,
	...
FROM
	object
WHERE
	thread_id = 123
	OR parent_id = 0

Проблема в том, что такой запрос не сможет использовать индексы.

В документации по MySQL предлагают оптимальное решение: заменить OR на UNION.
SELECT
	object_id AS id,
	...
FROM
	object
WHERE
	thread_id = 123
UNION
	SELECT
		object_id AS id,
		...
	FROM
		object
	WHERE
		parent_id = 0

В таком случае MySQL объединит результаты двух выборок, в каждой из которых будут использоваться индексы. При этом дублирующиеся записи будут пропущены.