Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Web программирование > SQL, базы данных
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 16.12.2014, 01:09   #1
sanich_23
 
Регистрация: 19.05.2007
Сообщений: 9
По умолчанию Оптимизация запроса с count(*)

Добрый день.

Уже голову сломал, пытаясь сделать запрос быстрее:

Запрос:
Код:
(select id_categ id,categ name_,order_ categ_order,-1  rubrika_order,' ' count_ from categ) 
union all
(select r.id_rubrika id, r.rubrika,c.order_, r.order_,
 (select count(*) from object o where now()<o.date_del and o.id_rubrika=r.id_rubrika) as count_ 
 from rubrika r ,categ c where r.id_categ=c.id_categ)
order by categ_order, rubrika_order
В таблице object 300000 записей
Потеря времени происходит в месте where now()<o.date_del
Если убрать, сравнение now()<o.date_del то запрос летает
Пробовал сделать индекс по полю date_del, ничего не изменилось.

план запроса во вложении

Как его можно оптимизировать?
Изображения
Тип файла: gif план-запроса.gif (15.4 Кб, 128 просмотров)

Последний раз редактировалось Stilet; 16.12.2014 в 07:58.
sanich_23 вне форума Ответить с цитированием
Старый 16.12.2014, 01:39   #2
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

А если вместо now() константу?
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 16.12.2014, 09:32   #3
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,526
По умолчанию

Код:
select r.id_rubrika id, r.rubrika, c.order_
, r.order_
, cnt.cnt_r as count_   --, ( select count(*) from object o where now()<o.date_del and o.id_rubrika=r.id_rubrika ) as count_ 
from rubrika r ,categ c
--------
left join ( select o.id_rubrika, count(*) as cnt_r 
            from object o where now()<o.date_del 
            group by o.id_rubrika
          ) as cnt on r.id_rubrika =cnt.id_rubrika
--------
where r.id_categ=c.id_categ
программа — запись алгоритма на языке понятном транслятору
evg_m вне форума Ответить с цитированием
Старый 16.12.2014, 15:25   #4
sanich_23
 
Регистрация: 19.05.2007
Сообщений: 9
По умолчанию

Цитата:
Сообщение от evg_m Посмотреть сообщение
Код:
select r.id_rubrika id, r.rubrika, c.order_
, r.order_
, cnt.cnt_r as count_   --, ( select count(*) from object o where now()<o.date_del and o.id_rubrika=r.id_rubrika ) as count_ 
from rubrika r ,categ c
--------
left join ( select o.id_rubrika, count(*) as cnt_r 
            from object o where now()<o.date_del 
            group by o.id_rubrika
          ) as cnt on r.id_rubrika =cnt.id_rubrika
--------
where r.id_categ=c.id_categ
Честно говоря не понял этого запроса,

Код:
select r.id_rubrika id, r.rubrika, c.order_
, r.order_
, cnt.cnt_r as count_, ( select count(*) from object o where now()<o.date_del and o.id_rubrika=r.id_rubrika ) as count_ 
from rubrika r ,categ c
left join ( select o.id_rubrika, count(*) as cnt_r 
            from object o where now()<o.date_del 
            group by o.id_rubrika
          ) as cnt on r.id_rubrika =cnt.id_rubrika
where r.id_categ=c.id_categ
Но в нем ошибка: Error Code : 1054
Unknown column 'r.id_rubrika' in 'on clause'
Не могу понять что не так, можете поправить?
sanich_23 вне форума Ответить с цитированием
Старый 16.12.2014, 16:40   #5
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,526
По умолчанию

Цитата:
Честно говоря не понял этого запроса,
Предложение эквивалентного запроса для этих строк Вашего кода
Цитата:
Код:
(select r.id_rubrika id, r.rubrika,c.order_, r.order_,
 (select count(*) from object o where now()<o.date_del and o.id_rubrika=r.id_rubrika) as count_ 
 from rubrika r ,categ c where r.id_categ=c.id_categ)
вместо того чтобы каждый раз считать количество для одного, считаем количество один раз но для всех(для каждого!)

Цитата:
Но в нем ошибка: Error Code : 1054
Код:
from rubrika r, categ c 
left join (....)
заменить на
Код:
from categ c, rubrika r 
left join (....)
можно еще сделать так
Код:
select r.id_rubrika id, r.rubrika, c.order_
, r.order_
, cnt.cnt_r as count_, ( select count(*) from object o where now()<o.date_del and o.id_rubrika=r.id_rubrika ) as count_ 
from rubrika r ,categ c ,
  ( ---подсчитать количество 
     select o.id_rubrika, count(*) as cnt_r 
    from object o where now()<o.date_del 
    group by o.id_rubrika  --по каждой категории
  ) as cnt --как таблица cnt
where r.id_categ =c.id_categ
  and  ---условие соединения "таблицы" cnt 
        r.id_rubrika =cnt.id_rubrika
программа — запись алгоритма на языке понятном транслятору
evg_m вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Оптимизация запроса russian-stalker SQL, базы данных 1 11.10.2011 13:17
Оптимизация запроса stalsoft SQL, базы данных 0 05.07.2011 14:51
оптимизация запроса pray_driver SQL, базы данных 3 13.12.2010 15:40
Оптимизация запроса za4ot SQL, базы данных 0 11.06.2010 09:24
функция запроса COUNT Таня84 БД в Delphi 1 10.06.2007 15:49