SQL запрос к ODBC
От: VVS  
Дата: 13.12.01 10:24
Оценка:
Привет всем.
Пишу прогу на VC++
Проблема такая:
есть две таблицы(1-T1,2-T2) одинаковые,со следующими полями Ф,И,О,DATE1,DATE2 .
1)Требуется добавить в 1 таблицу те строки из 2 таблицы в которых нет в 1 таблице
(проверка по Ф,И,О).
2)Также надо обновить DATE2 в 1 таблице из DATE2 2 таблицы
в тех строках где Ф,И,О 1 таблицы совпадают с Ф,И,О 2 таблицы.
SQL знаю плохо,вот что я намутил:
1)INSERT INTO T1 (Ф,И,О,DATE2)
SELECT Ф,И,О,DATE2 FROM T2 WHERE Ф NOT IN (SELECT DISTINCT Ф FROM T1)
OR И NOT IN (SELECT DISTINCT И FROM T1)
OR О NOT IN (SELECT DISTINCT О FROM T1)
Запрос работает но очень долго(когда в базе 10 000 строк)
2)UPDATE T1 a ,T2 b SET a.DATE2 =b.DATE2 WHERE a.Ф = b.Ф AND a.И=b.И AND a.О=b.О
тоже думаю что можно как то оптимизировать,помогите ктонить плиз,
может ктонибуть сможет в один запрос все засунуть:).
(отмечу что запрос к ODBC).
Заранее благодарен.
Re: SQL запрос к ODBC
От: VVV Россия  
Дата: 13.12.01 11:52
Оценка:
Здравствуйте VVS, Вы писали:

VVS>Привет всем.

VVS>Пишу прогу на VC++
VVS>Проблема такая:
VVS>есть две таблицы(1-T1,2-T2) одинаковые,со следующими полями Ф,И,О,DATE1,DATE2 .
VVS>1)Требуется добавить в 1 таблицу те строки из 2 таблицы в которых нет в 1 таблице
VVS>(проверка по Ф,И,О).
VVS>2)Также надо обновить DATE2 в 1 таблице из DATE2 2 таблицы
VVS>в тех строках где Ф,И,О 1 таблицы совпадают с Ф,И,О 2 таблицы.
VVS>SQL знаю плохо,вот что я намутил:
VVS>1)INSERT INTO T1 (Ф,И,О,DATE2)
VVS> SELECT Ф,И,О,DATE2 FROM T2 WHERE Ф NOT IN (SELECT DISTINCT Ф FROM T1)
VVS> OR И NOT IN (SELECT DISTINCT И FROM T1)
VVS> OR О NOT IN (SELECT DISTINCT О FROM T1)
VVS>Запрос работает но очень долго(когда в базе 10 000 строк)
VVS>2)UPDATE T1 a ,T2 b SET a.DATE2 =b.DATE2 WHERE a.Ф = b.Ф AND a.И=b.И AND a.О=b.О
VVS>тоже думаю что можно как то оптимизировать,помогите ктонить плиз,
VVS>может ктонибуть сможет в один запрос все засунуть.
VVS>(отмечу что запрос к ODBC).
VVS>Заранее благодарен.

1) может быть такая штука ускорит запрос
... WHERE 0=(SELECT COUNT(*) FROM T1 WHERE (T2.Ф=T1.Ф) AND (T2.И=T1.И) AND (T2.О=T1.О))
Re: SQL запрос к ODBC
От: Toughpheeckouse Россия  
Дата: 13.12.01 13:06
Оценка: 4 (1)
Здравствуйте VVS, Вы писали:

...
VVS>1)Требуется добавить в 1 таблицу те строки из 2 таблицы в которых нет в 1 таблице
VVS>(проверка по Ф,И,О).
т.е. получить дополнение одного мн-ва до другова типа вот запрос:
SELECT T1.ID, T1.F, T1.I, T1.O, T1.D1 FROM T1 
WHERE NOT EXISTS (SELECT NULL FROM T2 WHERE T2.F = T1.F and T2.I = T1.I and T2.O = T1.O)

VVS>2)Также надо обновить DATE2 в 1 таблице из DATE2 2 таблицы
VVS>2)UPDATE T1 a ,T2 b SET a.DATE2 =b.DATE2 WHERE a.Ф = b.Ф AND a.И=b.И AND a.О=b.О
тут вроде не чё добавить...

в первом запросе попутал тоблицы местами... думаю разбеоешься
Думайте сами, решайте сами...
Re[2]: SQL запрос к ODBC
От: Lexey Россия  
Дата: 13.12.01 13:24
Оценка:
Здравствуйте VVV, Вы писали:

VVV>1) может быть такая штука ускорит запрос

VVV>... WHERE 0=(SELECT COUNT(*) FROM T1 WHERE (T2.Ф=T1.Ф) AND (T2.И=T1.И) AND (T2.О=T1.О))

Едва-ли, скорее наоборот замедлит (если оптимизатор не разберется).
Re[3]: SQL запрос к ODBC
От: VVV Россия  
Дата: 13.12.01 13:38
Оценка:
Здравствуйте Lexey, Вы писали:

L>Здравствуйте VVV, Вы писали:


VVV>>1) может быть такая штука ускорит запрос

VVV>>... WHERE 0=(SELECT COUNT(*) FROM T1 WHERE (T2.Ф=T1.Ф) AND (T2.И=T1.И) AND (T2.О=T1.О))

L>Едва-ли, скорее наоборот замедлит (если оптимизатор не разберется).


ну уж не замедлит — это точно.
Re[4]: SQL запрос к ODBC
От: Lexey Россия  
Дата: 13.12.01 14:19
Оценка:
Здравствуйте VVV, Вы писали:

VVV>Здравствуйте Lexey, Вы писали:


L>>Здравствуйте VVV, Вы писали:


VVV>>>1) может быть такая штука ускорит запрос

VVV>>>... WHERE 0=(SELECT COUNT(*) FROM T1 WHERE (T2.Ф=T1.Ф) AND (T2.И=T1.И) AND (T2.О=T1.О))

L>>Едва-ли, скорее наоборот замедлит (если оптимизатор не разберется).


VVV>ну уж не замедлит — это точно.


Аргументы в студию?
Обратные аргументы: IN (SELECT ...) — SELECT выполняется всего один раз, потом просто идет сравнение хешей. Здесь же на каждую строку из T2 идет подзапрос по T1, что однозначно медленнее. Впрочем, это голое теоретизирование. Умный оптимизатор скорее всего сведет все к одному и тому же плану.
Re[5]: SQL запрос к ODBC
От: VVV Россия  
Дата: 13.12.01 14:56
Оценка:
Здравствуйте Lexey, Вы писали:

L>Здравствуйте VVV, Вы писали:


VVV>>Здравствуйте Lexey, Вы писали:


L>>>Здравствуйте VVV, Вы писали:


VVV>>>>1) может быть такая штука ускорит запрос

VVV>>>>... WHERE 0=(SELECT COUNT(*) FROM T1 WHERE (T2.Ф=T1.Ф) AND (T2.И=T1.И) AND (T2.О=T1.О))

L>>>Едва-ли, скорее наоборот замедлит (если оптимизатор не разберется).


VVV>>ну уж не замедлит — это точно.


L>Аргументы в студию?

L>Обратные аргументы: IN (SELECT ...) — SELECT выполняется всего один раз, потом просто идет сравнение хешей. Здесь же на каждую строку из T2 идет подзапрос по T1, что однозначно медленнее. Впрочем, это голое теоретизирование. Умный оптимизатор скорее всего сведет все к одному и тому же плану.

Ну теория, так теория
Отчего же в IN (SELECT ...) SELECT выполняется один раз??? Ведь для каждой Ф(И,О) из Т2 мы должны это сделать (к тому же там всё соединяется по OR, что плохо оптимизируется, а у меня по AND, что оптимизируется замечательно, ибо каждый следующий подзапрос будет происходить уже по подвыборке). Или не так? К тому же, опыт показывает, что запрос SELECT COUNT(*) выполняется быстрее, чем аналогичный без COUNT — видимо таковы внутренности драйвера (хотя это я проверял много лет назад, но впечатление осталось )
Теория без практики — не теория Предлагаю VVS опубликовать результаты, что, несомненно, будет очень полезно.
Re[6]: SQL запрос к ODBC
От: Lexey Россия  
Дата: 14.12.01 09:10
Оценка:
Здравствуйте VVV, Вы писали:

VVV>Здравствуйте Lexey, Вы писали:


L>>Здравствуйте VVV, Вы писали:


VVV>>>Здравствуйте Lexey, Вы писали:


L>>>>Здравствуйте VVV, Вы писали:


VVV>>>>>1) может быть такая штука ускорит запрос

VVV>>>>>... WHERE 0=(SELECT COUNT(*) FROM T1 WHERE (T2.Ф=T1.Ф) AND (T2.И=T1.И) AND (T2.О=T1.О))

L>>>>Едва-ли, скорее наоборот замедлит (если оптимизатор не разберется).


VVV>>>ну уж не замедлит — это точно.


L>>Аргументы в студию?

L>>Обратные аргументы: IN (SELECT ...) — SELECT выполняется всего один раз, потом просто идет сравнение хешей. Здесь же на каждую строку из T2 идет подзапрос по T1, что однозначно медленнее. Впрочем, это голое теоретизирование. Умный оптимизатор скорее всего сведет все к одному и тому же плану.

VVV>Ну теория, так теория

VVV>Отчего же в IN (SELECT ...) SELECT выполняется один раз??? Ведь для каждой Ф(И,О) из Т2 мы должны это сделать (к

А от чего ему больше выполняться? Он же не привязан к конкретному значению из T1. Там 3 таких селекта, ну выполнятся они по разу. И все.

>тому же там всё соединяется по OR, что плохо оптимизируется, а у меня по AND, что оптимизируется замечательно, ибо

>каждый следующий подзапрос будет происходить уже по подвыборке). Или не так? К тому же, опыт показывает, что запрос

По какой подвыбоке? У тебя из полного набора записей будет искаться строка с заданными значениями полей. По индексу это очень быстро, но все равно, на каждую запись в T1 — один поиск по идексу. Сомневаюсь, что это быстрее, чем один раз загрузить три выборки в память и пройтись по ним.

>SELECT COUNT(*) выполняется быстрее, чем аналогичный без COUNT — видимо таковы внутренности драйвера (хотя это я >проверял много лет назад, но впечатление осталось )


Это где он быстрее выполняется?

VVV>Теория без практики — не теория Предлагаю VVS опубликовать результаты, что, несомненно, будет очень полезно.


А вообще, зря мы спорим, т.к. исходный запрос-то был попросту неправилный (я на это даже и внимания сначала не обратил . Там OR-логика вообще не прокатывает. И в любом случае нужно делать что-то вроде уже упомянутого:
NOT EXISTS (SELECT ID1 FROM T1,T2 WHERE T1.Ф=T2.Ф AND ...). А такая конструкция почти точно будет эквивалентна твоей.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.