parser

Написать ответ на текущее сообщение

 

 
   команды управления поиском

Это несложный пример совсем не хорош....

Misha v.3 11.11.2002 20:02

Стремление к минимализму количества запросов не всегда хорошо, и то, что этот пример появился - очередное тому подтверждение.

Напиши перед запросом explain и посмотри... Увидишь что-то типа "type: ALL" и "Extra: Using temporary"

О чем это говорит?
Дока MySQL:
ALL
A full table scan will be done for each combination of rows from the previous tables. This is normally not good if the table is the first table not marked const, and usually very bad in all other cases. You normally can avoid ALL by adding more indexes, so that the row can be retrieved based on constant values or column values from earlier tables.

...

Using temporary
To resolve the query MySQL will need to create a temporary table to hold the result. This typically happens if you do an ORDER BY on a different column set than you did a GROUP BY on.
для того, чтобы вычесть из одного числа другое ты предлагаешь sql серверу полностью просканировать твои данные в форуме, создать из этого временную таблицу... ну... круто... :)

если ты сделаешь X запросов (X - кол-во форумов) вида
SELECT 
Count(tab1.id2) AS CountALL,
Sum(if(tab1.x, null, 1)) AS CountZero,
Count(tab1.id2) - Sum(if(tab1.x, null, 1)) AS XXXXX
FROM tab1
WHERE tab1.id1 = 'xID';
то работать будет уже быстрее (хотя при этом все равно будет полное сканирование таблицы)... не будет создаваться временная таблица и ты получишь пирожок от админов твоего SQL что перестанешь его "класть" :)

переделываем далее:
SELECT 
Count(*) AS CountALL
FROM tab1
WHERE tab1.id1 = 'xID';
и уже не имеем полного сканирования таблиц (All -> ref), начинают использоваться индексы и запрос делается моментально...

Т.е. я бы переделал приведенный пример и парсером-бы сделал несколько простеньких запросов...
А вообще, для решения подобного рода задач рекомендуется хранить статистику в отдельной табличке, и об этом пишут в той-же доке по MySQL.

Ты сам написал, что " SQL специально заточен под поиск и отбор данных!" - это верно, но то, что ты пытаешься заставить его делать - это не поиск и отбор...

опять его дока:
If you very often need to calculate things based on information from a lot of rows (like counts of things), it's probably much better to introduce a new table and update the counter in real time. An update of type UPDATE table set count=count+1 where index_column=constant is very fast! This is really important when you use databases like MySQL that only have table locking (multiple readers / single writers). This will also give better performance with most databases, as the row locking manager in this case will have less to do.
If you need to collect statistics from big log tables, use summary tables instead of scanning the whole table. Maintaining the summaries should be much faster than trying to do statistics 'live'. It's much faster to regenerate new summary tables from the logs when things change (depending on business decisions) than to have to change the running application!
ну и т.д.
а про твой вопрос: ответ - нельзя
Почему? Читай доку, там все есть:
A SELECT expression may be given an alias using AS. The alias is used as the expression's column name and can be used with ORDER BY or HAVING clauses.