Конференция "Базы" » Есть ли разница, что указывать вместо звездочки в count(*) ?
 
  • Piter © (30.10.09 15:51) [0]
    А есть ли разница в каких-то случаях, что писать внутри count?

    Может ли быть отличие
    count(*)

    от
    count(PK_name)

    , где PK_name - наименование поля primary key?
    Отличие в результатах (?!), в скорости исполнения? Что идеологически правильнее, почему?
  • McSimm © (30.10.09 16:00) [1]
    Раз primary key не может быть null, то разницы в результате не должно быть.
  • Sergey13 © (30.10.09 16:21) [2]
    ИМХО разница может быть в производительности для разных серверов. count(PK_name) может взять информацию и не из таблицы, а из индекса, что возможно шустрее. Хотя утверждать этого не возьмусь.

    > [1] McSimm ©   (30.10.09 16:00)

    Count-у вроде как пофиг null или не null.
  • Медвежонок Пятачок © (30.10.09 16:23) [3]
    каунт со звездой считает записи
    каунт с полем считает значения
  • Anatoly Podgoretsky © (30.10.09 16:23) [4]
    > Piter  (30.10.2009 15:51:00)  [0]

    Все зависит от результа, это ведь две разные функции, а не заменяющая одна другую.
    По скорости конечно count(*) быстрее, но при чем тут PK_name функции count это как то до лампочки.
    И конечно надо смотреть план выполнения.
  • Медвежонок Пятачок © (30.10.09 16:23) [5]
    и нулл это не значение
  • Сергей М. © (30.10.09 16:28) [6]

    > Anatoly Podgoretsky ©   (30.10.09 16:23) [4]


    > По скорости .. count(*) быстрее


    В версионниках это может не соответствовать действительности.
  • Anatoly Podgoretsky © (30.10.09 16:30) [7]
    > Sergey13  (30.10.2009 16:21:02)  [2]

    Не пофиг, результаты будут разные, только для ПК это бессмысленно, кроме возможной разницы в скорости.
  • Sergey13 © (30.10.09 16:40) [8]
    > [7] Anatoly Podgoretsky ©   (30.10.09 16:30)

    Да, действительно, проверил сейчас - считает только NOT NULL значения. Как то никогда об этом не задумывался.

    > [2] Sergey13 ©   (30.10.09 16:21)
    был не прав
  • Anatoly Podgoretsky © (30.10.09 16:52) [9]
    > Сергей М.  (30.10.2009 16:28:06)  [6]

    Читай про план, я писал
  • Piter © (30.10.09 18:20) [10]
    Медвежонок Пятачок ©   (30.10.09 16:23) [3]
    каунт со звездой считает записи
    каунт с полем считает значения


    расшифруй свою мысль? Или приведи пример запроса, где count(*) и count(<имя PK>) будут давать разные значения?
  • McSimm © (30.10.09 18:31) [11]

    > Piter ©   (30.10.09 18:20) [10]

    В данном случае речь не о разнице в результатах, а о разных операциях.
    В случае с PK количество записей совпадет с количеством значений. Результат одинаковый. Но операции будут выполнены разные.
  • McSimm © (30.10.09 18:33) [12]

    > с количеством значений

    точнее с количеством not null значений.
  • Медвежонок Пятачок © (30.10.09 19:42) [13]
    расшифруй свою мысль?

    Она не зашифрована.
    каунт со звездой считает строки.
    каунт с полем считает значения.
    нулл к значениям не относится.
  • Inovet © (30.10.09 20:33) [14]
    Можно посиотреть в запросе

    SELECT FLD1, FLD2, COUNT(FLD1), COUNT(FLD2), COUNT(*)
    FROM TBL
    GROUP BY FLD1, FLD2
    HAVING COUNT(FLD1) <> COUNT(FLD2) OR COUNT(FLD2) <> COUNT(*)


  • Кщд (02.11.09 08:45) [15]
    >Inovet ©   (30.10.09 20:33) [14]
    у меня данный запрос не выводит ничего - значит, разницы никакой нет, так?))
  • Inovet © (02.11.09 10:09) [16]
    > [15] Кщд   (02.11.09 08:45)
    > >Inovet ©   (30.10.09 20:33) [14]
    > у меня данный запрос не выводит ничего - значит, разницы
    > никакой нет, так?))

    В чём разница выше отвечали, а запрос одлжен её показать, я всё же наверно такой имел ввиду

    SELECT FLD1, COUNT(FLD1), COUNT(FLD2), COUNT(*)
    FROM TBL
    GROUP BY FLD1
    HAVING COUNT(FLD1) <> COUNT(FLD2) OR COUNT(FLD2) <> COUNT(*)


  • Кщд (02.11.09 11:36) [17]
    >Inovet ©   (02.11.09 10:09) [16]
    речь о том, что иллюстративность Вашего запроса весьма и весьма зависит от "магии данных"
    поэтому что именно он(запрос) призван доказать или опровергнуть - не ясно)
  • Inovet © (02.11.09 12:22) [18]
    > [17] Кщд   (02.11.09 11:36)
    > >Inovet ©   (02.11.09 10:09) [16]
    > речь о том, что иллюстративность Вашего запроса весьма и
    > весьма зависит от "магии данных"
    > поэтому что именно он(запрос) призван доказать или опровергнуть
    > - не ясно)

    Не призван он ничего доказать или опровергнуть, а показать различные значения сабжа, если таковые найдутся, можно убрать HAVING и искать глазами.
  • Кщд (02.11.09 12:38) [19]
    >Inovet ©   (02.11.09 12:22) [18]
    Здесь(Медвежонок Пятачок ©   (30.10.09 16:23) [3]) всё понятно написано

    >Не призван он ничего доказать или опровергнуть, а показать различные значения сабжа
    ещё раз: при отсутствии null-значений полей - искать нечего - различных значений просто не будет
  • Inovet © (02.11.09 13:35) [20]
    > [19] Кщд   (02.11.09 12:38)
    > ещё раз: при отсутствии null-значений полей - искать нечего
    > - различных значений просто не будет

    Вот и вернётся 0 записей.
  • stakan (03.11.09 14:15) [21]
    Наткнулся на интересную особенность.
    Oracle использует INDEX FAST FULL SCAN без доступа к таблице даже при запросе вида
    select count(*)

    .
    Причем на запросах вида select count(PK_NAME) может использовать НЕ индекс по полю PK_NAME, а индекс по другому not null полю. А если есть bitmap index, то использует его, даже если этот индекс построен по полю nullable.
  • Игорь Шевченко © (03.11.09 15:16) [22]
    stakan   (03.11.09 14:15) [21]


    > Oracle использует INDEX FAST FULL SCAN без доступа к таблице
    > даже при запросе вида select count(*).


    Если по списку предикатов определяется, что достаточно сканировать индекс. В противном случае будут сканироваться данные.

    Льюис на эту тему достаточно подробно пишет, в "Основах стоимостной оптимизации"
  • Кщд (04.11.09 09:59) [23]
    >stakan   (03.11.09 14:15) [21]
    Oracle использует тот метод доступа, который является более подходящим - согласно ли правилам или собранной статистике(RBO и CBO, соответственно, - что у вас там?) - поэтому четкие утверждения о том, что всегда используется Index FFS, безосновательны.
    С BI индексом - тоже всё ясно, т.к. он содержит null-значения, в отличие от B-tree индекса Oracle.
    Собирайте статистику и не ищите магию.
  • stakan (04.11.09 12:20) [24]

    > Oracle использует тот метод доступа, который является более
    > подходящим - согласно ли правилам или собранной статистике(RBO
    > и CBO, соответственно, - что у вас там?) - поэтому четкие
    > утверждения о том, что всегда используется Index FFS, безосновательны.
    >
    > С BI индексом - тоже всё ясно, т.к. он содержит null-значения,
    >  в отличие от B-tree индекса Oracle.
    > Собирайте статистику и не ищите магию.
    >

    Да это все понятно и логично, никакой магии нет. И то что
    > всегда используется Index FFS
    я не утверждал.
     Просто приятно удивила догадливость оптимизатора. Честно говоря, думал, что при запросах
    select count(*) from t

    оптимизатор выберет table scan.
  • Кщд (04.11.09 13:47) [25]
    >stakan   (04.11.09 12:20) [24]
    >Просто приятно удивила догадливость оптимизатора. Честно говоря, думал, что >при запросах select count(*) from t оптимизатор выберет table scan.
    хуже, когда догадливость переходит в "догадливость" для сложных запросов
    тогда приходится стабилизировать план вручную
  • Игорь Шевченко © (04.11.09 14:08) [26]
    Кщд   (04.11.09 13:47) [25]


    > тогда приходится стабилизировать план вручную


    Или чаще собирать статистику :)
  • Anatoly Podgoretsky © (04.11.09 14:46) [27]
    > stakan  (04.11.2009 12:20:24)  [24]

    В данном виде возмодно просто укажет количество записей, которое ему уже известно, без обращения к таблице или индексам.
  • Кщд (04.11.09 15:09) [28]
    >Игорь Шевченко ©   (04.11.09 14:08) [26]
    на некоторых старых системах это невозможно, т.к. сбор статистики жестко ударит по производительности, ввиду того, что разлетятся планы
    а ресурсов на переписывание системы просто нет...
    есть и второй аспект: иногда(особенно на сложных запросах), оптимизатор так забавно, простите, оптимизирует, что результаты запроса с нестабилизированным планом в худшую сторону(т.е. попросту бредовые) отличаются от явно прохинтованных - наверняка с таким встречались?
    это случается крайне редко и, конечно, вовсе не повод не собирать статистику или вставлять хинты куда  ни попадя
    имеется и третий аспект проблемы: во внутренних представлениях Oracle до сих пор можно встретить /*+ rule*/(тяжелое наследие индийской культуры) - поэтому в таких случаях, очевидно, собранная статистика не спасет
  • Игорь Шевченко © (04.11.09 16:04) [29]
    Кщд   (04.11.09 15:09) [28]


    > наверняка с таким встречались?


    Безусловно. Лечилось изменением запроса и следованием мантре "оптимизатор всегда прав" (он в 99,9% оказывается прав). Я стараюсь использовать хинты как можно реже, потому что без хинтов план запроса будет более оптимально подстраиваться под данные.


    > во внутренних представлениях Oracle до сих пор можно встретить
    > /*+ rule*/(тяжелое наследие индийской культуры)


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


    > сбор статистики жестко ударит по производительности


    Сбор статистики еще сам по себе занимает ресурсы, что тоже не положительно сказывается на производительности.
  • Кщд (05.11.09 08:44) [30]
    >Игорь Шевченко ©   (04.11.09 16:04) [29]
    >Безусловно. Лечилось изменением запроса и следованием мантре >"оптимизатор всегда прав" (он в 99,9% оказывается прав).
    на боевой системе изменение запроса не всегда возможно: элементарно нет понимания, какие данные должен вернуть запрос с точки зрения бизнеса, а знание это давно утеряно, т.к. разработчик уволился, постановщик болеет, а заказчик почил в бозе
    но проследить логику, заложенную разработчиком и заставить oracle делать именно то, что от него хотели - можно

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

    >Это не тяжелое наследие индийской культуры, это очень разумное >положение: работает - не трогай
    не согласен: ядро эволюционирует, но костыли остаются - это неправильно
    правило "работает - не трогай" работает для прикладных систем - спора нет, но такой подход ужасен в СУБД
    сбор статистики обязательно полезен был бы и для словаря данных, но - увы - вероятно, нет ресурсов на переписывание груды индийского кода
    явное хинтование rule'ом в ядре - это костыль и признание немощности разработчиком
    табу на сбор статистики в SYS - это ли не бред?)

    >Сбор статистики еще сам по себе занимает ресурсы, что тоже не >положительно сказывается на производительности.
    здесь можно лавировать технологическими перерывами и параметрами сбора статистики, но когда мы на стенде сделали сбор статистики на древней системе, перенесенной на 10g, испытали ужас и потрясение
  • ANB (06.11.09 13:01) [31]

    > перенесенной на 10g

    На 10-ке еще баги выплыли. Некоторые сильно усложняют жизнь.
  • Кщд (06.11.09 19:01) [32]
    >ANB   (06.11.09 13:01) [31]
    сильно осложняют особенно те, которые латать в 10-ке и не собираются)
    впрочем, надежды скачать 10.2.0.5 не оставляю
    подождем 11.2 и будем кочевать - как обычно
  • salexn (09.11.09 12:57) [33]
    Есть еще один нюанс.
    Предположим, что на какой-то столбец в таблице наложили ограничение по доступности - не доступен для чтения.
    Тогда SELECT count(*) не отработает, как и не отработает запрос
    SELECT COUNT(1)
  • Кщд (09.11.09 14:21) [34]
    >salexn   (09.11.09 12:57) [33]
    отличный нюанс - главное, подходящий для всех СУБД
 
Конференция "Базы" » Есть ли разница, что указывать вместо звездочки в count(*) ?
Есть новые Нет новых   [134435   +33][b:0][p:0.002]