Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2008.11.16;
Скачать: [xml.tar.bz2];

Вниз

Помогите с оптимизацией 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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.51 MB
Время: 0.009 c
2-1223451464
9899100
2008-10-08 11:37
2008.11.16
XLS c паролем :(


2-1223535224
D@nger
2008-10-09 10:53
2008.11.16
Drag-n-Drop файлов из проводника


15-1221717255
Chuvak
2008-09-18 09:54
2008.11.16
Настройки в реестре D2007


2-1223206467
ЛамоРщщук
2008-10-05 15:34
2008.11.16
Как найти все главные Окна и распредилить их по заголовку ?


15-1221741972
oldman
2008-09-18 16:46
2008.11.16
Все гениальное просто (или как бороться с простыми вирусами)...





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский