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

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

Вернуться   Форум программистов > Скриптовые языки программирования > PHP
Регистрация

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 18.03.2010, 23:30   #1
adwaer
Пользователь
 
Регистрация: 06.06.2008
Сообщений: 47
По умолчанию нужно оптимизировать код

Вобщем нужно вывести в из базы количество посещений страниц.
В названиях страниц в таблице не должны присутствовать передаваемые методом GET переменные. Например,
/folder/page.php?DNSID=fd44892a0f4d1cb7cc29 61baf511aea5
и
/folder/page.php?var=50&DNSID=a91373ce49306 662d9636e9e57ef6c01
- это одна и та же страница, в таблице она должна быть представлена как /folder/page.php

в базе хранится лог файл сервера апач. в виде:
id host date files serv_req traf
1 83.69.119.43 2005-12-25 / 200 17980
2 83.69.119.43 2005-12-25 /design/main.css 200 8795
....
41 213.180.217.8 2005-12-25 /contest/view.php?DNSID=0eb6ee75 ..

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

Код:
<?php
$db = mysql_connect ("localhost","admin","1234");
	mysql_select_db("tests",$db);
		
	$files = mysql_query("SELECT id, files
						FROM log",$db);	

	$row = mysql_fetch_array($files);
	do
	{	
		$page='empty';$k=0;
		while($k < strlen($row['files']))
		{
			if($row['files'][$k]=='.')
			{
				//проверка: нет ли параметров типа 'GET'
				if($k+4 < strlen($row['files']) && $row['files'][$k+4]=='?')
				{
					$page = substr($row['files'],0,$k+3);
				}
				else
				{
					$type = substr($row['files'],$k+1,5);
					if($type='php' || $type='html' || $type='/' || $type='htm' || $type='shtm' || $type='shtml' || $type='php3' || $type='phtml' || $type='phtm' || $type='txt')
					{
						$page = substr($row['files'],0,strlen($row['files']));
					}
				}
				$k++;
				//если не найдено расширение файла, следовательно это '/'
				if($k==strlen($row['files']) && $page=='empty')
				{
					$page = substr($row['files'],0,strlen($row['files']));
				}
				echo "$page<br>";
			}
		}	
	}
	while($row = mysql_fetch_array($files));
?>
adwaer вне форума Ответить с цитированием
Старый 18.03.2010, 23:57   #2
ADSoft
Старожил
 
Регистрация: 25.02.2007
Сообщений: 4,160
По умолчанию

чет недопонимаю.... сами говорите что в бд УЖЕ хранится лог апача.... и тут же - что там не должны быть записи такого типа (с параметрами)...

может вам из существующей бд просто выборку сделать с условиями?

этот запрос не сработает но мысль донесет - выборка по левой части строки и группировка.. я думаю в мускуле есть такие возможности
Код:
SELECT id, file from log group by left(file)
ADSoft вне форума Ответить с цитированием
Старый 19.03.2010, 00:15   #3
adwaer
Пользователь
 
Регистрация: 06.06.2008
Сообщений: 47
По умолчанию

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

Цитата:
может вам из существующей бд просто выборку сделать с условиями?
Вопрос в том с какими уловиями?

Цитата:
Код:
SELECT id, file from log group by left(file)
А вот это очень отличная идея, большое спасибо. Время загрузки сократится на много.
Но все равно, этого не достаточно, нужно сократить время загрузки. В выборке останется где то 10000 строк, заносить такое в массив тоже не из быстрых действий..
нужно придумать какое то условие что ли.. или алгоритм сделать по короче..
adwaer вне форума Ответить с цитированием
Старый 19.03.2010, 05:34   #4
Johnatan
Antimoderаtoris
Участник клуба
 
Регистрация: 08.02.2008
Сообщений: 1,251
По умолчанию

Код:
$files = mysql_query("SELECT id, SUBSTRING_INDEX(`file`, '?', 1) file FROM log", $db);
Данная выборка 27000 строк занимает чуть более секунды. Я так и не понял что именно автор хочет сделать с 27000 строк ОДНОВРЕМЕННО. Может всё-таки разбить сие хозяйство на отдельные страницы? И выводить по 100 строк, например.
27000 строк занимают около 2.5Мб в чистом виде. Вы это всё читать собрались? Зачем вывод на экран? Какова вообще идея данного скрипта?

Кстати, скрипт автора неработоспособен. Он зацикливается на обработке первой же строчки. Использование while необдуманно может быть очень опасно.
98% из тысячи моих постов сделаны в профильном подфоруме. Я не накручиваю свои посты болтанием в "курилке", а ты?
Johnatan вне форума Ответить с цитированием
Старый 19.03.2010, 08:25   #5
adwaer
Пользователь
 
Регистрация: 06.06.2008
Сообщений: 47
По умолчанию

Оо вообще круто! Я даже не знал такой функции.. Спасибо!
Из этих строк будет делать отчёт о наиболее посещаемых страницах.
Код терь такой, работает очень даже ничего:
Цитата:
<?php
$db = mysql_connect ("localhost","admin","1234");
mysql_select_db("tests",$db);

$files = mysql_query("SELECT id, SUBSTRING_INDEX(`files`, '?', 1) files FROM log",$db);

$row = mysql_fetch_assoc($files);
while($row = mysql_fetch_assoc($files))
{
if(($qpos = strpos($row['files'], '?')) === false) {
$url = $row['files'];
} else {
$url = substr($row['files'], 0, $qpos);
}
echo $url . '<br />';
}
?>
adwaer вне форума Ответить с цитированием
Старый 19.03.2010, 09:56   #6
ADSoft
Старожил
 
Регистрация: 25.02.2007
Сообщений: 4,160
По умолчанию

тут же он все строки выдаст?
Код:
$files = mysql_query("SELECT id, SUBSTRING_INDEX(`files`, '?', 1) files FROM log",$db);
а может группировку ввести по страницам и кол-во еще подсчитывать? типа
Цитата:
$files = mysql_query("SELECT id, count(id), SUBSTRING_INDEX(`files`, '?', 1) files FROM log group by SUBSTRING_INDEX(`files`, '?', 1)",$db);
ADSoft вне форума Ответить с цитированием
Старый 19.03.2010, 15:50   #7
VY_CMa
Пользователь
 
Аватар для VY_CMa
 
Регистрация: 13.03.2010
Сообщений: 38
По умолчанию

Используйте системы кеширования на сервере, APC + nginx, далее кеширование самих скриптов, вырвите функции из phpbb форума
VY_CMa вне форума Ответить с цитированием
Старый 19.03.2010, 16:42   #8
Johnatan
Antimoderаtoris
Участник клуба
 
Регистрация: 08.02.2008
Сообщений: 1,251
По умолчанию

Я бы настоятельно советовал делать "обрезание" строки с путём во время ДОБАВЛЕНИЯ в базу, то есть во время парсинга логов апача.
А ещё лучше сделать таблицу статистики посещений типа "id, path, count" - и обновлять её во время парсинга логов апача. Таким образом скорость обращения к такой странице будет мгновенной, а основная нагрузка будет приходиться на момент парсинга (минус тут в том, что статистика получается "отложенной", а не в реальном времени).
98% из тысячи моих постов сделаны в профильном подфоруме. Я не накручиваю свои посты болтанием в "курилке", а ты?
Johnatan вне форума Ответить с цитированием
Старый 20.03.2010, 01:09   #9
adwaer
Пользователь
 
Регистрация: 06.06.2008
Сообщений: 47
По умолчанию

Спасибо всем, сделал неожиданно просто, одним sql-запросом =)
Цитата:
<?php
$db = mysql_connect ("localhost","admin","1234");
mysql_select_db("tests",$db);

$rezult = mysql_query("SELECT SUBSTRING_INDEX( `files` , '?', 1 ) AS files, COUNT(host) AS c
FROM log
WHERE SUBSTRING_INDEX( `files` , '?', 1 ) LIKE '%.htm' OR
SUBSTRING_INDEX( `files` , '?', 1 ) = '/' OR
SUBSTRING_INDEX( `files` , '?', 1 ) LIKE '%/' OR
SUBSTRING_INDEX( `files` , '?', 1 ) LIKE '%.html' OR
SUBSTRING_INDEX( `files` , '?', 1 ) LIKE '%.shtml' OR
SUBSTRING_INDEX( `files` , '?', 1 ) LIKE '%.shtm' OR
SUBSTRING_INDEX( `files` , '?', 1 ) LIKE '%.php' OR
SUBSTRING_INDEX( `files` , '?', 1 ) LIKE '%.php3' OR
SUBSTRING_INDEX( `files` , '?', 1 ) LIKE '%.phtm' OR
SUBSTRING_INDEX( `files` , '?', 1 ) LIKE '%.phtml' OR
SUBSTRING_INDEX( `files` , '?', 1 ) LIKE '%.txt'
GROUP BY files
ORDER BY c DESC
LIMIT 10",$db);
$row = mysql_fetch_assoc($rezult);
$i=1;
do
{
printf("
<tr class='table'>
<td>%s</td>
<td>%s</td>
<td>%s</td>
</tr>
", $i, $row['files'], $row['c']);
$i++;

}
while($row = mysql_fetch_assoc($rezult));
?>

Последний раз редактировалось adwaer; 20.03.2010 в 14:17.
adwaer вне форума Ответить с цитированием
Старый 20.03.2010, 16:06   #10
Johnatan
Antimoderаtoris
Участник клуба
 
Регистрация: 08.02.2008
Сообщений: 1,251
По умолчанию

Какая-то дурацкая привычка в последнее время появилась. Делать вот так:
$row = mysql_fetch_assoc($rezult);
do
{...}
while($row = mysql_fetch_assoc($rezult));
Оптимизировать код и делать вот так - это как ехать на полной скорости на Порше с ручником.
98% из тысячи моих постов сделаны в профильном подфоруме. Я не накручиваю свои посты болтанием в "курилке", а ты?
Johnatan вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Оптимизировать код копирования tae1980 Microsoft Office Excel 3 27.02.2009 21:43
Что нужно оптимизировать? nemoomen Microsoft Office Excel 13 27.02.2009 06:28
Помогите оптимизировать код tae1980 Microsoft Office Excel 2 11.02.2009 23:24
Оптимизировать код. Манжосов Денис :) Общие вопросы Delphi 1 20.10.2008 19:06
Оптимизировать код NeiL Помощь студентам 2 21.02.2008 08:57