очень долго выполняются запросы в БД

Статус
В этой теме нельзя размещать новые ответы.

RomikChef

Guest
клевел.
заканчивай сопли жевать.

ответь четко и, по возможности, подробно, что должен делать твой запрос.

ты так и не ответил, что делает строка
FROM_UNIXTIME(copy.hit,'%Y%m')<FROM_UNIXTIME(statistic.hit,'%Y%m')
сам я понять этого не могу. потому, что я понимаю, когда дата сравнивается с константой. у тебя же получается
"где дата в статистике меньше, чем дата в статистике"

Дальше.
Пока у тебя 2000 записей, ты можешь сделать и так:
в конце концов, тупо, в лоб, считать построчно информацию из базы, как будто она у тебя лежит в файле, и построчно же и обработать.
Больше секунды не займет.

Учти, я сам всегда бью по рукам за такие "советы". Делать надо, как правильно, а не как легче. Темб более, что на больших размерах базы этот способ не проканает.
я просто тебе хочу проиллюстрировать, что есть другие способы.

Но помочь тебе можно, только если мы будем знать, ЧЕГО ТЕБЕ НАДО получить.

НЕ ДЕЛАЙ, КАК ШТИРЛИЦ!
ОТВЕЧАЙ НЕ ТОЛЬКО НА ПОСЛЕДНИЙ ВОПРОС.
когда будешь отвечать - внимательно перечитывай мое сообщение, и ответь, пожалуйста, на все вопросы.

В мире милионы систем статистики, все ониработают на базе баз данных. Спайлог работает на mysql.
вся проблема только в том, чтобы правильно составить запрос.
 

clevel

Новичок
FROM_UNIXTIME(copy.hit,'%Y%m')<FROM_UNIXTIME(statistic.hit,'%Y%m')
отвечаю воторой раз на этот вопрос: эта строка дает условие при выборке, что данные, выводимые запросом принадлежат предыдцщим меясцам...
например, есть 3 месяца года, 200201,200202,200203,
запрос ищет всех посетителей прошлых месяцев для каждого месяца, то есть для 200203 в 200202,200201, для 200202 в 200201, при этом users должны совпадать в предыдущих месяцах с текущим..
человеческим языком это называется: найти номера постоянных пользователей, которые были на сайте в прошлые месяцы и зглянули в этом - только такая выборка нужны по каждому месяцу...
что не понятно?
насчет выборки как из файла... хотелось бы либо нормальный запрос либо уже в файле, не надо извращаться... 2 тысячи записей это тест, в реале будет сотни тысяч, сам понимаешь...
 

RomikChef

Guest
на файле из сотни тысяч у ты подохнешь вместе со своим скриптом.

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

clevel

Новичок
1. три месяца - это пример, заранее я не знаю, сколько месяцев... ведь вывод то сводной статистики за ВСЕ месяцы.
2.серьезно подумываю насчет доп полей типа год месяца, день месяца, час для того, что функции конвертации не использовать и поставить индексы на эти поля...
при таком раскладе нормально будет?
3.если я делаю запрос по конкретному месяцу, значит ли это, что данные за другие месяцы даже не будут просомтрены (с т.з. производительности системы)?
4.с сотней тысяч записей разве пхп+мускул не потянет? что тогда использовать?

П.С.: сейчас пока на файлах работает.... могут ли быть проблемы с ошибками доступа к файлу при большом количестве пользователей:
1.каждый пользователь открывает с правами "a", добавляет запись в конец файла статистики за месяц (не храню все в одном файле), закрывает файл. Никаких флоков не использую.
2.раз в месяц кроном сканю статистику за последний месяц и делаю сводные данные по нужным критериям, например, сводную по месяцам, и записываю это в отдельный файл, например, months.
3.порядок скорости при кол-ве записей в стони тысяч в файле.. есть ли какие либо показатели скорости чтения из файла, например 5 мегов в секунду либо что-то подобное?
 

clevel

Новичок
решил провести эксперимент с рабочими характеристиками для двух вариантов - статистика на файлах и статистика на БД:

1.создал файл с месячной статистикой, кол-во записей 884215.
причем дата - ЮНИКСОВАЯ, отдельно поля с номером месяца года нет. записи сделал путем копирования пхп скриптом начальных 115 записей до нужного кол-ва раз в цикле.
размер файла - 12,14 мега.
вывожу статистику по месяцам (предыдущий единственный месяц- 100 записей), которая включает выборку уникальных месяцев, кол-во страниц (не уникальных) по каждому месяцу, кол-во уникальных юзеров, кол-во юзеров предыдущих месяцев (последнее очень актуально, так как в БД это жутко тормозит). время выполнения 26.4854 секунд.
2. создаю в БД 70987 записей, чуть меньше, чем в файле, ну да ладно.. важен порядок чисел... при этом создаю поле месяц (month) года int(4) с данными 9910, где 99-2099 год,10 - номер месяца.., так как where owner=2 and stat.month<copy.month
создаю индекс на owner,month
размер данных 24,263 мега, индекса - 10,745 мега, итого 35,008 мега.
делаю выборку только месяцев уникальных и кол-во юзеров для каждого месяца. время выполнения запроса - 28.4232 секунд, при добавлении запроса о выборке юзеров предыдущих месяцев запрос начинает выполняться несколько минут, у меня не хватает терпения и я его останавливаю..
запросы с БД простые:
1.SELECT month,COUNT(page),COUNT(DISTINCT(user)),SUM(execute)/count(execute)
FROM statistic
WHERE owner=2
GROUP BY 1
ORDER BY 1
выбирает уникальные месяцы, кол-во уникальных пользователей за каждй месяц, кол-во просмотренных страниц за месяц, среднее время выполенния скрипта за месяц...
2. выборка юзеров предыдущих периодов:
SELECT statistic.month,COUNT(DISTINCT(copy.user))
FROM statistic,statistic copy
WHERE statistic.owner=2
AND copy.owner=statistic.owner
AND copy.month<statistic.month
AND statistic.user=copy.user
GROUP BY 1
Какие будут мнения насчет производительности?
 

RomikChef

Guest
1. три месяца - это пример.
КТО тебе мешает выбрать сначала одним запросом, который выполнится за долю секунды эти самые месяцы, а потом в цикле считать статистику по месяцам?
2. насчет доп полей - не знаю. Может, и стоит.
А может - инет.
Эта задача мне не по зубам. Тебе тоже, но тебя это не смущает.
но если делать, как я сказал выше, то такие поля не будут нужны.
3. Будут.
Твоя проблема не в том, что все записи просматриваются, а в том, что они просматриваются 2 тысячи раз.
4. Потянет. Забудь то, что я сказал, если не смог понять.
В спайлоге миллионы записей.

По поводу файлов.
Во-первых, по поволду файлов никто тут с тобой говорить не будет.Если ты хочешь быть еще большим идиотом, чем ты есть на самом деле, то можешь это делать в одиночестве. Если бубут находиться такие же незнайки со взором горящим, то я буду больно бить их по почкам.
Ведь ты не понимаешь даже такой элементарной вещи, что база данных ТОЖЕ хранится в файле! в обычном файле на диске!
И дело не в скорости считывания информации из файла, а в скорости обработки.
Это во-вторых.

Это по первому письму.
 

RomikChef

Guest
1. про файлы я уже сказал. иди с ними в другое место.

2. SUM(execute)/count(execute)
ты ВПОЛНЕ можешь делать скриптом.
Я не уверен, что это сильно облегчит запрос, но все же соломинка.

2. COUNT(DISTINCT(user)),
вот это, я думаю, тормозит сильнее.
попробуй убрать пока - посчитаем потом.

И ПОЙМИ НАКОНЕЦ, ЧТО ИДИОТИЗМ СЧИТАТЬ, ЧТО ХОРОШИЙ ЗАПРОС - ЭТО ОДИН ЗАПРОС.
Очень часто несколько запросов оказываются быстрее, чем один но навороченный.

Кстати, если бы ты удосужился хоть что-нибудь почитать по той работе, за которую взялся, то узнал бы, что mysql КАК РАЗ И ОПТИМИЗИРОВАНА для БЫСТРОГО выполнения МЕЛКИХ запросов.

Это тебе не оракл.

И прекрати свои ламерские замашки. Я их уже еле терплю.
Нихера не слушать, что тебе говорят, нихера не делать, как тебе говорят, рождать в своем сумеречном мозгу какие-то идеи, и приходить спрашивать - будет ли это работать? какие мнения про производительность!
Никакой производительности не будет.
 

clevel

Новичок
Ладно, не горячись... я тебя понял...
вот что приходит на ум:
1.можно не генерить каждый раз статистику, просматривая ВСЮ базу данных, можно в крон поставить скрипт, который будет просматривать данные за определнный период, раскидывать по таблицам, где хранятся сводные данные, а проанализированные данные в основной таблице удалять.. таким образом, работа упрощается, так как кол-во записей будет не миллионы, а тысячи... это хороший выигрыш как при добавлении записей во время просмотра сайта, так и при выводе результатов статистики, так как уже ничего не надо подсчитывать... только вывести данные...
2.смущает в использовании мускула только одно - он не оперирует понятиями предыдущий и последующий элемент....
для того, чтобы это реализовать (например, найти страницы, разница по времени в просмотре которых составляет более 10 мин), приходиться либо скидывать с мучкула всю инфу в пхп и там разбирать, либо делать запросом в БД, используя два left join:

SELECT COUNT(t1.page),
t1.page
FROM statistic t1
LEFT JOIN statistic t2 ON t2.user = t1.user
AND t1.hit - t2.hit > 600
AND t1.owner=t2.owner
LEFT JOIN statistic t3 ON t3.user = t1.user
AND t3.hit > t2.hit AND t3.hit < t1.hit
AND t1.owner=t3.owner
WHERE t3.hit IS NULL
AND t1.owner=2
AND t2.hit IS NOT NULL
GROUP BY t1.user,2
П.С.: по поводу идиотизма... есть несколько точек зрения на любую проблему... я столкнулся с тем, что файловая система работает в моем случае несколько быстрее... однако я понимаю, что БД должна быть лучше, так ка ктам предусмотрены многие алгоритмы, сортировки, разграничения доступа, и т.д.... БД скомпилирована как бинарник, в конце концов...
поэтому я и ищу выходы, чтобы исользовать БД, однако чтобы при этом производительность была приличной и мой скрипт не сдох при 100 посещениях в день.... :)) это доказывает, что я еще не до конца выжил из ума...

Кстати, если бы ты удосужился хоть что-нибудь почитать по той работе, за которую взялся, то узнал бы, что mysql КАК РАЗ И ОПТИМИЗИРОВАНА для БЫСТРОГО выполнения МЕЛКИХ запросов.
дай пару ссылок на хорошую доку, а то я мануал по мускулу уже весь облизал с ног до головы, но там мало инфы, например по индексам.
 
Статус
В этой теме нельзя размещать новые ответы.
Сверху