упрощение запроса.

antonim

Новичок
упрощение запроса.

Помогите плз ускорить роиск в запросах:

1.

UPDATE series
SET name_series =
(SELECT second.name_series
FROM series first, series second
WHERE (char_length(second.name_series) > char_length(first.name_series)
OR char_length(second.name_series) = char_length(first.name_series))
AND series.id_series = second.id_series
AND second.id_series = first.id_series
AND second.data_add > first.data_add

)

WHERE id_series IN
(SELECT first.id_series
FROM series first, series second
WHERE (char_length(second.name_series) < char_length(first.name_series)
OR char_length(second.name_series) = char_length(first.name_series))
AND second.id_series = first.id_series
AND second.data_add > first.data_add)


Записей много и делает оч долго (несколько минут)

и к этому запросу нужно написать запрос удаляющий все записи с одинаковыми "id", но у которых second.data_add > first.data_add

пока в замешательстве как это сделать



2. Очень долго выполняется запрос поиска. Поиск производиться по большой базе, но вот думаю как же оптимизировать этот запрос:




PHP:
$result = pg_query("	
SELECT $slot 					   		   	
FROM book 								
WHERE (LOWER(name) LIKE LOWER('%$search%') 								
OR year::varchar LIKE LOWER('%$search%') 								
OR LOWER(ISBN) LIKE LOWER('%$search%')) 								
AND (my_book = 0) 								
ORDER BY name 								
LIMIT 10 OFFSET '$offset' 		
");
Буду очень рад любой помощи.
 

Glazyrin Sergey

Новичок
Ну не знаю я так думал почему бы не юзать ILIKE ?
И еще момент почему бы вам не поставить первым my_book = 0
Это по поводу второго
А вот по поводу первого надо думать - там чо то сложное
 

Sad Spirit

мизантроп (Старожил PHPClub)
Команда форума
Автор оригинала: Glazyrin Sergey
Ну не знаю я так думал почему бы не юзать ILIKE ?
И еще момент почему бы вам не поставить первым my_book = 0
Б#я, ну и клоун.

По первому запросу некисло было бы показать схему и уточнить, что именно ты пытаешься им сделать.

По второму --- неплохо бы попытаться использовать полнотекстовый поиск. По крайней мере для поиска по названию, что-то мне подсказывает, что люди обычно не ищут по куску года выхода и по куску ISBN.
 

antonim

Новичок
Автор оригинала: Sad Spirit
Б#я, ну и клоун.


По первому запросу некисло было бы показать схему и уточнить, что именно ты пытаешься им сделать.

По второму --- неплохо бы попытаться использовать полнотекстовый поиск. По крайней мере для поиска по названию, что-то мне подсказывает, что люди обычно не ищут по куску года выхода и по куску ISBN.
По первому:

Есть таблица с дублирующимися "id" (не уникален id). Также поля - дата - имя.
Нужно заменить в старой записи поле "имя", если длинна имени в "новом" поле с таким же id больше или равна "старому" полю.


Еще нужно будет дописать к этому запросу запрос удаляющий все "новые" дублирущиеся по "id" записи.

По второму:

Большое спасибо за подсказку. Кому нужно тоже самое, вот отличный ресурс : http://www.sai.msu.su/~megera/postgres/talks/fts_pgsql_intro.html#ftssync

Осталось только разобраться как искать в нем для поиска по 1-й букве каждого слова...
 

Sad Spirit

мизантроп (Старожил PHPClub)
Команда форума
Автор оригинала: antonim
По первому:

Есть таблица с дублирующимися "id" (не уникален id). Также поля - дата - имя.
Нужно заменить в старой записи поле "имя", если длинна имени в "новом" поле с таким же id больше или равна "старому" полю.
Вот как-то так, думаю всяко быстрее двух подзапросов будет:
Код:
UPDATE series
SET name_series = longer.name_series
FROM series as longer
WHERE (char_length(longer.name_series) > char_length(series.name_series)
       OR char_length(longer.name_series) = char_length(series.name_series))
      AND longer.id_series = series.id_series
      AND longer.data_add > series.data_add
Запрос не тестировал, так что возможны варианты

Еще нужно будет дописать к этому запросу запрос удаляющий все "новые" дублирущиеся по "id" записи.
Как-то типа
Код:
delete from series
where exists (
    select 1
    from series as older
    where older.id_series = series.id_series and
         older.data_add < series.data_add
)
Опять не тестировал

Осталось только разобраться как искать в нем для поиска по 1-й букве каждого слова...
Никак, он не для этого предназначен. Если речь о поиске по первой букве записи, то можно построить по ней функциональный индекс.
 

Mols

Новичок
не могу понять почему
Код:
WHERE (char_length(longer.name_series) > char_length(series.name_series)
       OR char_length(longer.name_series) = char_length(series.name_series))
а не
Код:
WHERE char_length(longer.name_series) >= char_length(series.name_series)
?

-~{}~ 28.01.09 23:35:

Да и вообще. Всё таки по этому "первому запросу" надо скорее всего не запрос менять. А логику. Очень всё странно... дублируются ИД. после изменения "старой" - удалять "новые"... Может просто вместо добавления "новой" сделать нормальный апдейт "старой"?
 

Sad Spirit

мизантроп (Старожил PHPClub)
Команда форума
Автор оригинала: Mols
Да и вообще. Всё таки по этому "первому запросу" надо скорее всего не запрос менять. А логику. Очень всё странно... дублируются ИД. после изменения "старой" - удалять "новые"... Может просто вместо добавления "новой" сделать нормальный апдейт "старой"?
Ну это само собой... Но у автора темы тут уже наблюдается поганая привычка назадавать вопросов и свалить, не давая обратной связи. Пожалуй в следующий раз будем его пытать значительно дольше.
 

antonim

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

По поводу:

WHERE char_length(longer.name_series) >= char_length(series.name_series)

Выдает ошибку, а так :

WHERE (char_length(longer.name_series) > char_length(series.name_series)
OR char_length(longer.name_series) = char_length(series.name_series))

не выдает вот и приходиться извращаться
 

Mols

Новичок
1.
Код:
WHERE char_length(longer.name_series) >= char_length(series.name_series)
должно работать. Думаю ошибка в чём-то другом.

2. на сайте постгреса вполне достойная документация http://www.postgresql.org/docs/

3. причем тут триггер вообще не понятно.
 

antonim

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

Mols

Новичок
при повторном "запихивании" уже известен ИД, и этот ИД вставляется с другими (обновлённым) данными? ТАк в чем проблема написать нормальный
Код:
UPDATE ... WHERE id= idFromProgramm AND char_length(name_series) >= char_length(in_name_series)
?
 
Сверху