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

Вниз

Что быстрее ?   Найти похожие ветки 

 
Undert ©   (2004-07-21 19:53) [0]

Функция проверки наличия "детей" у объекта

$r = mysql_query ("select id from tasks where parentid=$id");
$rn = mysql_numrows ($r);
if ($rn>0) {return true;} else {return false;};

или

$r = mysql_query ("select count(*) from tasks where parentid=$id");
$f = mysql_fetch_array($r);
if ($f[0]>0) {return true;} else {return false;};

или

$r = mysql_query ("select count(id) from tasks where parentid=$id");
$f = mysql_fetch_array($r);
if ($f[0]>0) {return true;} else {return false;};


 
VMcL ©   (2004-07-21 21:20) [1]

>>Undert ©  (21.07.04 19:53)

Честно говоря в SQL не силен, но может так?

select id
from tasks
group by id
having count(*) > 0
where parentid = $id


P.S. Это PHP? Тогда замени:
if ($rn>0) {return true;} else {return false;};
на
return $rn > 0;


 
VMcL ©   (2004-07-21 21:23) [2]

>>Undert ©  (21.07.04 19:53)

Кстати, если не ошибаюсь, то в MySql что-то типа профайлера есть. Можно "померять" скорость. Только данных, естественно, много нужно, чтобы не сравнивать 0.3 мс с 0.31 мс.


 
Undert ©   (2004-07-21 23:04) [3]

VMcL ©  
Да, PHP, Только это просто урезанная версия здесь... посему там ковычки стоят - было кое-что :))

И я про то же - пробовал explain и всякие stat команды - нечего сравнивать - менее 1 сек, но когда это деревцо вырастет - будет заметно, но сравнивать уж будет поздно :))


 
ИдиотЪ   (2004-07-22 10:25) [4]

select id from tasks where parentid=$id по идее быстрее, если поставить ограничение вернуть только одну запись, не знаю, как это сделать в  MySql
count(*) по любому должен не быстрее count(id), просто обработка во-втором случае только одного поля, если конечно принципы работы баз данных схожи


 
Sandman25 ©   (2004-07-22 10:31) [5]

[4] ИдиотЪ   (22.07.04 10:25)

count(*) быстрее, чем count(поле).
Во втором случае поле проверяется на Null.

Я бы попробовал
select 1
 from таблица_с_одной_строкой
 where exists
   (select 1
     from task
     where parentid=$id
   )

В этом случае оптимизатор не пытается найти/посчитать всех детей.


 
Соловьев ©   (2004-07-22 10:33) [6]


> Функция проверки наличия "детей" у объекта

триггеры же есть уже в Мускуле? тогда лучше всего завести поле где хранить флаг наличия детей.В принцыпе можно и без триггера..


 
Sandman25 ©   (2004-07-22 10:34) [7]

Если это MySQL, то боюсь, что мой вариант не пойдет из-за отсутствия поддержки вложенных select


 
ИдиотЪ   (2004-07-22 10:37) [8]

Sandman25 ©
я не спорю, если это действительно так в MySQL
но я знаю точно, что в Oracle это медленнее


 
Sandman25 ©   (2004-07-22 10:39) [9]

[8] ИдиотЪ   (22.07.04 10:37)

Тогда это проблемы Oracle. Такое поведение count(*), count(поле) и count(distinct поле) регламентировано стандартами SQL, причем начиная с самого раннего.


 
Nikolay M. ©   (2004-07-22 10:40) [10]

Имхо, два последних варианта равнозначны, первый - дольше, т.к. время идет на фетч. Возможно, будет tot лучше, если к первому варианту добавить в конце LIMIT 1


 
ИдиотЪ   (2004-07-22 10:44) [11]

Sandman25 ©  
это не проблемы Oracle, он просто умно использует индексы, оттого и быстрее бывает, тем более, что в индексах пресловутые null не хранит
но лучше сделать экспериментальные таблицы на несколько тысяч и проверить, чего быстрее, чем выяснять у кого пальцы шире


 
Sandman25 ©   (2004-07-22 10:52) [12]

[11] ИдиотЪ   (22.07.04 10:44)

Если Oracle считает по индексам, то делает он это либо по индексу parentid, либо по индексу (parentid, id).
Находит первую подходящую запись, далее, для count(*):
a)увеличивает счетчик
b)переходит на следующую запись
c)проверяет parent id и переходит на a) при необходимости
Для count(id):
a)проверяет id на Null
b)увеличивает счетчик
c)переходит на следующую запись
d)проверяет parent id и переходит на a) при необходимости

Если id не позволяет null, то, скорее всего, оптимизатор пропускает шаг a) второго алгоритма. Но даже, в этом случае, будет надежнее использовать count(parentid) вместо count(id), чтобы хотя бы не считывать значение id - ведь оно нам не нужно на самом деле. А еще лучше, count(*), чтобы не зависеть от оптимизатора.


 
ИдиотЪ   (2004-07-22 11:04) [13]

Sandman25 ©
а лучше count(1), чтоб вообще не зависеть
хотя кто знает, всегда ли числа будут


 
Sandman25 ©   (2004-07-22 11:25) [14]

Интересно. Не уверен, что такая конструкция допустима. SQL Explorer ругается, Capability not supported, на другой СУБД пока проверить не могу.


 
VMcL ©   (2004-07-22 11:28) [15]

>>Undert ©  (21.07.04 23:04) [3]

>нечего сравнивать

Наполни базу сам (программно, конечно). В чем проблема?


 
Sandman25 ©   (2004-07-22 11:29) [16]

count(1) не поддерживается. Проверял на Informix


 
kaif ©   (2004-07-22 11:37) [17]

Как минимум, создай индес по полю parent_id.
 Если нужно найти детей только у одного объекта, то тогда самая быстрая конструкция, я думаю, будет 2, так как MySQL быстро умеет считать count(*).
 Но это особенности MySQL.
 А вообще самая быстрая конструкция должна была бы быть:
 $r = mysql_query ("select count(id) from tasks where parentid=$id limit 1, 1");
 Если нужно не только у одного объекта, но у всех увидеть, я бы вообще завел специальное поле HAS_CHILDREN булевого типа и записывал бы в него 1 если создается "дочерний объект" и 0 - если последний "дочерний" на этом уровне удаляется.
 Сам я с MySQL не работаю - работаю с IB.


 
ИдиотЪ   (2004-07-22 11:41) [18]

Sandman25 ©
жаль, но я знаю, что хорошие идеи из Oracle перешли в стандарт 92
кто знает, может чего еще добавят
хотя последний стандарт полностью не реализовал никто


 
Sandman25 ©   (2004-07-22 11:41) [19]

[17] kaif ©   (22.07.04 11:37)

$r = mysql_query ("select count(parentid) from tasks where parentid=$id limit 1, 1");

не быстрее?


 
Sandman25 ©   (2004-07-22 11:43) [20]

[18] ИдиотЪ   (22.07.04 11:41)

Неужели в Oracle есть
select count(5) from ...
?

Возвращает то же, что и
select 5*count(*) from ...
?


 
ИдиотЪ   (2004-07-22 11:46) [21]

Sandman25 ©
В том-то и прикол, что есть )

SELECT COUNT(1)
FROM dual
---------------
1

SELECT COUNT(5)
FROM dual
---------------
1

SELECT COUNT(null)
FROM dual
---------------
0


 
Sandman25 ©   (2004-07-22 11:49) [22]

[21] ИдиотЪ   (22.07.04 11:46)

Ужас...
По-моему, очень похоже на
cast (var as boolean)


 
ИдиотЪ   (2004-07-22 11:53) [23]

Sandman25 ©  
ближе к условию var is null, но на уровне компиляции, а не выполнения, что лучше

но что-то уже в сторону не в ту ...


 
Sandman25 ©   (2004-07-22 11:55) [24]

Значит, select count(0) вернет 1...Понятно.
Спасибо за расширение моего кругозора :)


 
ИдиотЪ   (2004-07-22 11:59) [25]

Sandman25 ©
вернет не 1, а количество строк )


 
Sandman25 ©   (2004-07-22 12:21) [26]

Понятно.
if var is null then
 Result := 0
else
 select count(*)
   into Result
   from ...


 
Undert ©   (2004-07-22 13:03) [27]

Всем спасибо !!!



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

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

Наверх




Память: 0.53 MB
Время: 0.046 c
3-1089838751
CAMCOH
2004-07-15 00:59
2004.08.08
SQL запрос в Adoquery


4-1088495287
QSpeller
2004-06-29 11:48
2004.08.08
Как сделать всплывающую подсказку в системном трэе в XP?


3-1089797728
CAMCOH
2004-07-14 13:35
2004.08.08
немогу разобратся с try...except...


1-1090684174
Mental_Ray
2004-07-24 19:49
2004.08.08
Тупой вопрос: как перевести байты в Кб, Мб? :)


14-1089947765
Думкин
2004-07-16 07:16
2004.08.08
Пятничные задачки (прошу не судить строго)