Запрос для извлечения старых данных (импортированных из идентичных БД) и новых данных с помощью объединений
Кратко: я импортировал данные из существующих приложений с идентичными базами данных. Существует множество таблиц, поэтому обновление данных с помощью новых идентификаторов было невозможно. Существующий первичный ключ для каждой таблицы, например, serviceprovider - sp_id. Для всех таблиц я добавил новый идентификатор первичного ключа. Мне нужно получить старые и новые данные (после импорта) из этих таблиц. Чтобы получить старые данные, я использую старые первичные / внешние ключи и сравниваю database_id для таблиц, из которых они соединяются, откуда они были импортированы. Новые данные используют только новый идентификатор первичного ключа. Я знаю, если это новые данные по тому факту, что старый первичный ключ имеет значение 0.
select serviceprovider.* from serviceprovider sp
inner join services ss on ((sp.id = ss.sp_id) AND (ss.ss_id = 0))
OR ((sp.sp_id = ss.sp_id) AND (ss.ss_id <> 0) AND (sp.database_id=ss.database_id))
Я построил этот запрос, который становится очень медленным по мере увеличения данных. Первоначально это работало хорошо, но когда я импортировал данные из старых баз данных, он почти перестал работать. Как вы можете догадаться, мне нужно присоединиться к большему количеству таблиц, чтобы получить полные данные. Все таблицы используют один и тот же механизм объединения. Я использую MySQL. Можно ли перестроить запрос, чтобы повысить производительность?
1 ответ
Этот запрос не должен быть таким тяжелым, пожалуйста, рассмотрите возможность добавления индекса для всех соединяемых таблиц:
serviceprovider(id,sp_id,database_id)
services(sp_id,ss_id,database_id)
Это должно ускорить этот запрос.
Вы также можете попытаться перестроить свой запрос с помощью EXISTS() вместо внутреннего соединения:
select serviceprovider.* from serviceprovider sp
WHERE EXISTS(select 1 from services ss
where ((sp.id = ss.sp_id) AND (ss.ss_id = 0))
OR ((sp.sp_id = ss.sp_id) AND (ss.ss_id <> 0) AND (sp.database_id=ss.database_id)))
Возможно, он будет работать быстрее.
РЕДАКТИРОВАТЬ: Давайте попробуем другой подход, два выбора и объединение вместо этого условия ИЛИ:
select serviceprovider.* from serviceprovider sp
inner join services ss on (sp.id = ss.sp_id AND ss.ss_id = 0)
UNION ALL
select serviceprovider.* from serviceprovider sp
inner join services ss on(sp.sp_id = ss.sp_id AND ss.ss_id <> 0 AND sp.database_id=ss.database_id)