Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.11.16;
Скачать: CL | DM;

Вниз

Помогите с оптимизацией SQL запроса   Найти похожие ветки 

 
DelphiN!   (2008-10-07 14:50) [0]

Добрый день.
Есть задача, нужно синхронизировать файлы на клиентском компьютере с каталогом на серверном.

Есть 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 часу и еще не известно сколько он будет выполнятся. Данное время выполнения очень велико, можно ли как либо увеличить скорость выборки?


 
Поросенок Винни-Пух ©   (2008-10-07 15:02) [1]

скока показывает вот такое?

select count(*) from serverft srv
      full join clientft cnt on
      (srv.FileName = cnt.FileName)


 
Anatoly Podgoretsky ©   (2008-10-07 15:17) [2]

Есть вопросы

1. FILENAME VARCHAR (1000)
почему 1000? Когда максимально 260

2. BASEDIR VARCHAR (255)
почему 255, а не 260

3. BASEDIR VARCHAR (255)
readme.txt в разных BASEDIR это разные файлы или нет.


 
Anatoly Podgoretsky ©   (2008-10-07 15:20) [3]

Кстати как думаешь, сколько времени займет формирования соединения из 22 500 000 000 записей?


 
Поросенок Винни-Пух ©   (2008-10-07 15:21) [4]

меньше. у него же есть аж одно условие, ограничивающее декартово произведение.


 
Anatoly Podgoretsky ©   (2008-10-07 15:22) [5]


> Поросенок Винни-Пух ©   (07.10.08 15:02) [1]

Думаешь, что это он сможет дождаться?


 
Поросенок Винни-Пух ©   (2008-10-07 15:23) [6]

ну добавить гигов 300 памяти и вполне.


 
Anatoly Podgoretsky ©   (2008-10-07 15:23) [7]

Не намного.
Кстати меня очень интересует, как может быть FileName is null


 
DelphiN!   (2008-10-07 15:43) [8]


> Поросенок Винни-Пух ©   (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ух больших списков с файлами?


 
DelphiN!   (2008-10-07 15:46) [9]


> 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:54) [10]


> Кстати как думаешь, сколько времени займет формирования
> соединения из 22 500 000 000 записей?


В результате должно получится не более 150 000 + 150 000 = 300 000 записей, а вот сравнений да, получается 22 500 000 000


 
Anatoly Podgoretsky ©   (2008-10-07 15:55) [11]

> DelphiN!  (07.10.2008 15:46:09)  [9]

Все равно неясно, что такое FILENAME тогда


 
Поросенок Винни-Пух ©   (2008-10-07 15:57) [12]

у тебя слишком мало условий в открытом соединении.
и поэтому слишком много записей в итоговой выборке

а каунт 300 000 записей - это вопрос секунд и ее долей.
но у тебя там не 300 000 записей, а те самые 22 миллиарда


 
DelphiN!   (2008-10-07 15:58) [13]


> Anatoly Podgoretsky ©   (07.10.08 15:55) [11]


FileName - Имя файла например C:\1.txt


 
Правильный$Вася   (2008-10-07 15:59) [14]


> На все поля в обоих таблицах стоят индексы.

is null индексы не использует
<> индексы не использует


 
Поросенок Винни-Пух ©   (2008-10-07 15:59) [15]

Этот запрос выполняется тоже долго

спрашивалось не про долго/быстро, а про сколько оно показывает в результате каунта.


 
DelphiN!   (2008-10-07 16:00) [16]


> Поросенок Винни-Пух ©   (07.10.08 15:57) [12]


Ну а что мне сделать тогда чтобы найти отличающиеся фалы за приемлемое время?(максимально допустимое время выполнения SQL запроса 1 час)


 
Поросенок Винни-Пух ©   (2008-10-07 16:15) [17]

Ну а что мне сделать

озвучить здесь результат каунта из [1]


 
MsGuns ©   (2008-10-07 16:37) [18]

>Есть задача, нужно синхронизировать файлы на клиентском компьютере с каталогом на серверном.

Стесняюсь спросить: а нафига это надо ?


 
Виталий Панасенко   (2008-10-07 16:39) [19]

А если просто тупо UNION?
В первой выбрать отличные на сервере от клиентской, во  второй - наоборот...Ну, ввести фиктивное поле-признак, откуда выборка("SERVER"/"CLIENT" , 0/1 - как угодно)


 
DelphiN!   (2008-10-08 06:06) [20]


> Поросенок Винни-Пух ©   (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]
>
> Стесняюсь спросить: а нафига это надо ?


Есть большое количество компьютеров в сети Интернет кафе, нужно чтобы на одном из компьютеров стоял эталонных хард и по очереди проверял каждый компьютер на отличия от эталона, после делая хард проверяемого клиента приближенным к эталону. Удобно для обновления программ, удаления старых и т.д.


 
DelphiN!   (2008-10-08 06:08) [21]


> Поросенок Винни-Пух ©   (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 08:11) [22]


> Виталий Панасенко   (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)



Страницы: 1 вся ветка

Текущий архив: 2008.11.16;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.016 c
15-1221368214
Sergey Masloff
2008-09-14 08:56
2008.11.16
Компьютер дохнет. Нужны идеи


15-1221991549
Кое кто
2008-09-21 14:05
2008.11.16
Скачивалка


2-1223130000
Dr. Genius
2008-10-04 18:20
2008.11.16
InputQuery – ввод пароля


2-1223361774
feel
2008-10-07 10:42
2008.11.16
Написание БД на Delphi6 с нуля.


2-1223026415
Развёртка
2008-10-03 13:33
2008.11.16
Развернуть досовское окноий экран программы на весь экран