![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Помогите с оптимизацией SQL запроса [FireBird 2.1]
DelphiN! © (2008-10-07 14:50:00)Добрый день.
Есть задача, нужно синхронизировать файлы на клиентском компьютере с каталогом на серверном.
Есть 2 таблицы ServerFT и ClientFT, с одинаковыми полями :
FILENAME VARCHAR (1000)
BASEDIR VARCHAR (255)
FILESIZE BIGINT
FILECRC BIGINT
ID INTEGER PRIMARY KEY
На все поля в обоих таблицах стоят индексы.
Обе таблицы в начале очищаются, а потом в них заносится примерно по 150 000 записей(найденые файлы на 2х компьютерах - файлы найденые на сервере заносятся в таблицу ServerFT, а файлы найденые на клиенте в таблицу ClientFT),
далее выполняется поиск отличающихся друг от друга записей в разных таблицах(поиск отличающихся или отсутствующих на одном компе, но присутствующих на другом файлов). Выполняю поиск различий следующим SQL запросом :
select
srv.FileName Srv_FName, cnt.FileName Cnt_FName,
srv.FileSize Srv_FSize, cnt.filesize Cnt_FSize,
srv.filecrc Srv_FCRC, cnt.FileCRC Cnt_FCRC,
srv.BASEDIR Srv_BaseDir, cnt.BASEDIR Cnt_BaseDir
from serverft srv
full join clientft cnt on
(srv.FileName = cnt.FileName)
where ((srv.filename is null)or(cnt.filename is null))
or(cnt.filesize <> srv.FileSize)or(cnt.filecrc <> srv.filecrc)
Данный SQL запрос уже выполняется около 1 часу и еще не известно сколько он будет выполнятся. Данное время выполнения очень велико, можно ли как либо увеличить скорость выборки?
DelphiN! (2008-10-08 08:11:00) [1]
> Виталий Панасенко (07.10.08 16:39) [19]
>
> А если просто тупо UNION?
> В первой выбрать отличные на сервере от клиентской, во
> второй - наоборот...Ну, ввести фиктивное поле-признак, откуда
> выборка('SERVER'/'CLIENT' , 0/1 - как угодно)
Точно! Спасибо большое!
Вместо громадного количества часов выполняется меньше чем за секунду, а результат тот же что мне и нужен!
select srv.FileName Srv_FName, cnt.FileName Cnt_FName,
srv.FileSize Srv_FSize, cnt.filesize Cnt_FSize,
srv.filecrc Srv_FCRC, cnt.FileCRC Cnt_FCRC,
srv.BASEDIR Srv_BaseDir, cnt.BASEDIR Cnt_BaseDir
from serverft srv
right join clientft cnt on
(srv.FileName = cnt.FileName)
where ((srv.filename is null)or(cnt.filename is null))
or(cnt.filesize <> srv.FileSize)or(cnt.filecrc <> srv.filecrc)
union
select srv.FileName Srv_FName, cnt.FileName Cnt_FName,
srv.FileSize Srv_FSize, cnt.filesize Cnt_FSize,
srv.filecrc Srv_FCRC, cnt.FileCRC Cnt_FCRC,
srv.BASEDIR Srv_BaseDir, cnt.BASEDIR Cnt_BaseDir
from serverft srv
left join clientft cnt on
(srv.FileName = cnt.FileName)
where ((srv.filename is null)or(cnt.filename is null))
or(cnt.filesize <> srv.FileSize)or(cnt.filecrc <> srv.filecrc)
DelphiN! (2008-10-08 06:08:00) [2]
> Поросенок Винни-Пух © (07.10.08 16:15) [17]
select count(*) from serverft srv
full join clientft cnt on
(srv.FileName = cnt.FileName)
122 458
Plan
PLAN JOIN (CNT NATURAL, SRV NATURAL)
Adapted Plan
PLAN JOIN (CNT NATURAL, SRV NATURAL)
------ Performance info ------
Prepare time = 0ms
Execute time = 12h 37m 47s 109ms
Avg fetch time = 45 467 109,00 ms
Current memory = 34 269 756
Max memory = 34 546 900
Memory buffers = 2 048
Reads from disk to cache = 4 160
Writes from cache to disk = 0
Fetches from cache = 1 308 655 418
DelphiN! (2008-10-08 06:06:00) [3]
> Поросенок Винни-Пух © (07.10.08 15:59) [15]
>
> Этот запрос выполняется тоже долго
>
> спрашивалось не про долго/быстро, а про сколько оно показывает
> в результате каунта.
> Поросенок Винни-Пух © (07.10.08 15:02) [1]
>
> скока показывает вот такое?
>
> select count(*) from serverft srv
> full join clientft cnt on
> (srv.FileName = cnt.FileName)
122 458
Execute time = 12h 37m 47s 109ms
> MsGuns © (07.10.08 16:37) [18]
>
> Стесняюсь спросить: а нафига это надо ?
Есть большое количество компьютеров в сети Интернет кафе, нужно чтобы на одном из компьютеров стоял эталонных хард и по очереди проверял каждый компьютер на отличия от эталона, после делая хард проверяемого клиента приближенным к эталону. Удобно для обновления программ, удаления старых и т.д.
Виталий Панасенко (2008-10-07 16:39:00) [4]А если просто тупо UNION?
В первой выбрать отличные на сервере от клиентской, во второй - наоборот...Ну, ввести фиктивное поле-признак, откуда выборка('SERVER'/'CLIENT' , 0/1 - как угодно)
MsGuns (2008-10-07 16:37:00) [5]>Есть задача, нужно синхронизировать файлы на клиентском компьютере с каталогом на серверном.
Стесняюсь спросить: а нафига это надо ?
Поросенок Винни-Пух (2008-10-07 16:15:00) [6]Ну а что мне сделать
озвучить здесь результат каунта из [1]
DelphiN! (2008-10-07 16:00:00) [7]
> Поросенок Винни-Пух © (07.10.08 15:57) [12]
Ну а что мне сделать тогда чтобы найти отличающиеся фалы за приемлемое время?(максимально допустимое время выполнения SQL запроса 1 час)
Поросенок Винни-Пух (2008-10-07 15:59:00) [8]Этот запрос выполняется тоже долго
спрашивалось не про долго/быстро, а про сколько оно показывает в результате каунта.
Правильный$Вася (2008-10-07 15:59:00) [9]
> На все поля в обоих таблицах стоят индексы.
is null индексы не использует
<> индексы не использует
DelphiN! (2008-10-07 15:58:00) [10]
> Anatoly Podgoretsky © (07.10.08 15:55) [11]
FileName - Имя файла например C:\1.txt
Поросенок Винни-Пух (2008-10-07 15:57:00) [11]у тебя слишком мало условий в открытом соединении.
и поэтому слишком много записей в итоговой выборке
а каунт 300 000 записей - это вопрос секунд и ее долей.
но у тебя там не 300 000 записей, а те самые 22 миллиарда
Anatoly Podgoretsky (2008-10-07 15:55:00) [12]> DelphiN! (07.10.2008 15:46:09) [9]
Все равно неясно, что такое FILENAME тогда
DelphiN! (2008-10-07 15:54:00) [13]
> Кстати как думаешь, сколько времени займет формирования
> соединения из 22 500 000 000 записей?
В результате должно получится не более 150 000 + 150 000 = 300 000 записей, а вот сравнений да, получается 22 500 000 000
DelphiN! (2008-10-07 15:46:00) [14]
> Anatoly Podgoretsky © (07.10.08 15:17) [2]
>
> Есть вопросы
>
> 1. FILENAME VARCHAR (1000)
> почему 1000? Когда максимально 260
>
> 2. BASEDIR VARCHAR (255)
> почему 255, а не 260
>
> 3. BASEDIR VARCHAR (255)
> readme.txt в разных BASEDIR это разные файлы или нет.
Размеры FileName и BaseDir подправлю ...
Поле BaseDir не участвует в условии, а используется для внутренних нужд программы ...
DelphiN! (2008-10-07 15:43:00) [15]
> Поросенок Винни-Пух © (07.10.08 15:02) [1]
select count(*) from serverft srv
full join clientft cnt on
(srv.FileName = cnt.FileName)
Этот запрос выполняется тоже долго
> Anatoly Podgoretsky © (07.10.08 15:23)
Кстати меня очень интересует, как может быть FileName is null
ServerFT.FileName is null может быть если на сервере файла нет, а на клиенте - есть
ClientFt.FileName is null может быть если файа на клиенте нет, а на сервере есть.
Кстати как думаешь, сколько времени займет формирования соединения из 22 500 000 000 записей?
А как можно быстрее определить различия в 2ух больших списков с файлами?
Anatoly Podgoretsky (2008-10-07 15:23:00) [16]Не намного.
Кстати меня очень интересует, как может быть FileName is null
Поросенок Винни-Пух (2008-10-07 15:23:00) [17]ну добавить гигов 300 памяти и вполне.
Anatoly Podgoretsky (2008-10-07 15:22:00) [18]
> Поросенок Винни-Пух © (07.10.08 15:02) [1]
Думаешь, что это он сможет дождаться?
Поросенок Винни-Пух (2008-10-07 15:21:00) [19]меньше. у него же есть аж одно условие, ограничивающее декартово произведение.
Anatoly Podgoretsky (2008-10-07 15:20:00) [20]Кстати как думаешь, сколько времени займет формирования соединения из 22 500 000 000 записей?