[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Проблема с быстродействием запроса
Renden
Доброго времени, несколько месяцев назад благодаря форуму написал стрипт вывода трафика, все было ок но теперь тк колличество записей уже около 250 тысяч запрос выполняеться около 5 секунд, поковыряв его понял что 90% времени прибавляет left join on.
Для сравнения:

SELECT t.trafd_to, trafd_from, trafd_port, trafd_all,trafd_date FROM traffic t left join users on users.ip=t.trafd_to

Time: 4.378ms

SELECT trafd_to, trafd_from, trafd_port, trafd_all,trafd_date FROM traffic

Time: 0.285ms
Косяк в том что в users содержаться имена пользователей приравненые к ip в строке trafd_to, и пользователям просто показывать ип нельзя, непоймут + неэстетично)
Вопрос, что лутьше сделать, тк через еще несколько месяцев чую будет 10 сек.. а через годик минуту ждать нехочеться никак)))




Спустя 6 минут, 52 секунды (26.01.2011 - 14:50) Evilsoul написал(а):
SELECT * FROM `traffic`, `users` WHERE `users.ip`= `trafic`.`t.trafd_to`

а на выводе не выводи айпи

Спустя 1 минута (26.01.2011 - 14:51) Evilsoul написал(а):
если указать столбцы, то быстрее будет

Спустя 12 минут, 11 секунд (26.01.2011 - 15:03) Renden написал(а):
Evilsoul
Цитата
[Err] 1054 - Unknown column 'users.ip' in 'where clause'

хотя такой столбец есть но он его не видит тк видимо смотрит в таблицу traffic

а понял..кавычки

Спустя 6 минут, 26 секунд (26.01.2011 - 15:10) Evilsoul написал(а):
ошибся я
так напиши `users`.`ip`

Да %)

Спустя 7 минут, 6 секунд (26.01.2011 - 15:17) Evilsoul написал(а):
Где результат, какая скорость?
Мне же тоже интересно smile.gif

Спустя 6 минут, 27 секунд (26.01.2011 - 15:23) Renden написал(а):
Evilsoul

SELECT CONCAT(lastname,' ',firstname,' ',middlename) AS host, trafd_to, trafd_from, trafd_port,
trafd_all,trafd_date FROM `traffic`, `users` WHERE `users`.`ip`= `traffic`.`trafd_to`

Time: 0.325ms
да лутьше спасибо, тока косяк в том что я в данный запрос подсовывал дополнительное условие типа where host="$host" так вот, если я подсуну имя то все будет ок, тк в результате имя содержиться, а если я подсуну ип, то к сожалению инфы мне не предоставиться..А хотелось бы, чтоб ослеживать тех кто меняет апишники например, или в нашу сеть в с ноута вотнулся, (а в базе users егож нет еще)

Но всеравно спс, так лутьше чем ждать..

подредактировал, раздражает что перенос не работает в тегах..

Спустя 23 минуты, 56 секунд (26.01.2011 - 15:47) Renden написал(а):
Evilsoul
Попробывал так:

SELECT IFNULL (CONCAT(lastname,' ',firstname,' ',middlename) ,t.trafd_to) AS host,
users.id from traffic t left join users on users.ip=t.trafd_to WHERE t.trafd_to LIKE '%192.168.2%'

Time: 2.412ms
Так айпишники внутреней подстети попадают, и запрос длится меньше, но всеравно долго..(

Спустя 3 минуты, 48 секунд (26.01.2011 - 15:51) Evilsoul написал(а):
Дай больше кода, желательно входящие параметры.
LIKE не нужно, нужно LIMIT и навигацию и будет у тебя запрос торпеда biggrin.gif

Спустя 17 минут, 45 секунд (26.01.2011 - 16:09) Renden написал(а):
Evilsoul
Ну работает примерно так:
Если хотим получить всю инфу допустим об ip 192.168.2.1 получаем его гетом, если хотим за день мосмотреть с ипом еще передаем date..(ну и также там месяцы, недели, вырезал дабы не захламлять)

if (isset($_GET['host'])) {
if (isset($_GET['date'])) {
$dd = check($_GET['date'])
$addsql = "and trafd_date='".$dd."'";
}
$qwery = mysql_query("SELECT IFNULL (CONCAT(lastname,' ',firstname,' ',middlename) ,t.trafd_to) AS host,
users.id from traffic t left join users on users.ip=t.trafd_to WHERE t.trafd_to LIKE '%192.168.2%' HAVING host ='
$host'" $addsql);
ну тут циклом выводим
}


И чесно говоря невижу смысла LIMIT ставить...(тк максимум есть сылка на месяц(за год я для себя оставил))

Спустя 51 минута, 55 секунд (26.01.2011 - 17:01) Evilsoul написал(а):
А почему бы просто не добавить это host ='$host' в WHERE
вот так:
WHERE `users`.`ip`= `traffic`.`trafd_to` AND `host` ='$host' 

ну и в хост имя таблицы добавить через точку.

Спустя 18 часов, 14 минут, 3 секунды (27.01.2011 - 11:15) Renden написал(а):
Evilsoul, если ты про мой последний запрос то: нельзя использовать псевдонимы (AS host) в условии where..
Если ты про свой запрос, то вывод идет же только тех ip что есть в таблице users.ip, (WHERE `users`.`ip`= `traffic`.`trafd_to`) те что просто содержаться в traffiс.trafd_to не выводяться, а как я уже говорил мне бы хотелось иметь к ним доступ.

Спустя 22 минуты, 28 секунд (27.01.2011 - 11:37) Evilsoul написал(а):
Выводятся ё-маё :) AS тебе не нужен
Давай упростим запрос, выведем все столбики
SELECT * FROM `traffic`, `users`, ещё тбл., ещё тбл. (пиши все с которых хочешь что-то получить) 
WHERE `users`.`ip`= `traffic`.`trafd_to`
AND и продолжаем ставить условия через and тех совпадений что нас интересуют

Спустя 1 час, 10 минут, 57 секунд (27.01.2011 - 12:48) sergeiss написал(а):
Оптимизация запроса - это хорошо smile.gif Но вот еще вопрос: у тебя индексация таблиц сделана и она правильная? И что говорит EXPLAIN о том, как будет выполняться запрос?

Спустя 1 час, 5 минут, 9 секунд (27.01.2011 - 13:53) Renden написал(а):
Evilsoul
мы походу просто говорим о разном, либо я не понимаю, либо ты)

SELECT * FROM `traffic`, `users` WHERE `users`.`ip`= `traffic`.`trafd_to`
AND `traffic`.`trafd_to`='192.168.2.240'

Так ничего не выводит, но такой ип есть в таблице traffic, в столбце trafd_to. А не выводит я думаю потому что условие не может стработать так как в таблице users этого ип нет.

SELECT * FROM `traffic`, `users` WHERE `users`.`ip`= `traffic`.`trafd_to`
AND `users`.`firstname`='Денис'

А так сработает, тк условие выполниться.
Но мне надо чтоб если ip в таблице users совпадает с trafd_to в таблице traffic выводило Имя юзеров, если нет выводило просто оставшиеся адреса из trafd_to.
sergeiss
Индексы какие-то есть, но неуверен что они верны, тк добавлял через navicat, толковой инфы по индексам не нашел в гугле.

Спустя 1 час, 8 минут, 39 секунд (27.01.2011 - 15:02) linker написал(а):
Renden
Ну ты уточни про индексы, без них да еще и при использовании varchar под IP - грустно.

Спустя 14 минут, 18 секунд (27.01.2011 - 15:16) Evilsoul написал(а):
Цитата
Так ничего не выводит, но такой ип есть в таблице traffic, в столбце trafd_to. А не выводит я думаю потому что условие не может стработать так как в таблице users этого ип нет.

конечно, так нужно подставить то что соответствует в одной и другой таблице

Спустя 1 час, 56 минут, 42 секунды (27.01.2011 - 17:13) Renden написал(а):
linker
Мне посоветовали использовать char, незнаю лутше это или хуже.
По поводу индексов если есть информация как их добавить, буду благодарен.
Evilsoul
Ну вот какраз фишка в том что я беру данные какраз только из 1 таблицы, а в другой я подлючаю дополнительные поля с Именем Фамилией если таковые имеються, я даже незнаю как тут можно обойтись без left join on.


Спустя 5 минут, 26 секунд (27.01.2011 - 17:18) Dron19 написал(а):
Renden , сделай постраничную навигацию и выводи на страницу по 20 айпи например, запрос будет нагружен всего 20ти записями smile.gif

Спустя 37 минут, 12 секунд (27.01.2011 - 17:55) Evilsoul написал(а):
Dron19
см. выше

Спустя 2 минуты, 17 секунд (27.01.2011 - 17:58) Evilsoul написал(а):
Renden
покажи структуру таблицы а то мы тут мусолим уже третий день huh.gif , названия столбцов и желательно хотя бы по пару строк которые в них

Спустя 15 минут, 36 секунд (27.01.2011 - 18:13) Dron19 написал(а):
Цитата (Evilsoul @ 27.01.2011 - 14:55)
Dron19
см. выше

а че уже говорили про навигацию? Просто не прочитал все...

Спустя 15 часов, 17 минут, 59 секунд (28.01.2011 - 09:31) linker написал(а):
Renden
Из IP-адреса легко получается целочисленное значение, которое можно обратно превратить в IP.
Как добавить индекс
ALTER TABLE `table` ADD INDEX `indexname` (`columnname`)

Спустя 1 час, 20 минут, 26 секунд (28.01.2011 - 10:52) Renden написал(а):
linker
И как это сделать?
Хм..значит индексы всеже есть уже, я так и добавлял...
Evilsoul
Итак чтоб у вас была вся информация:
traffic
user posted image
users
user posted image

$host = "Айпи адрес или имя пользователя";
$addsql = "and month(trafd_date)=".$mm." and YEAR(trafd_date)=".$year.""; //Аяксом передаю выбраный месяц и год.
$qwery = mysql_query("SELECT IFNULL (CONCAT(lastname,' ',firstname,' ',middlename) ,t.trafd_to)
AS host, t.trafd_to, trafd_from, trafd_port, trafd_all,trafd_date FROM traffic t left join users on
users.ip=t.trafd_to HAVING host ='
$host' $addsql ORDER by trafd_all DESC");
# Пояснение CONCAT тут для того чтоб обьединить 3 столбца в 1.
# IFNULL выводит IP если подставить Имя из таблицы users не удалось.
# Время такого запроса Time: 4.750ms, а строк всего 164(за месяц по одному из ip адресов)..



Спустя 16 минут, 47 секунд (28.01.2011 - 11:08) Evilsoul написал(а):
если я правильно понял, так айпи у тебя совпадают с таблицы traffic и users
и где у тебя столбик HAVING host ='$host' хост?

Спустя 52 минуты, 36 секунд (28.01.2011 - 12:01) Renden написал(а):
Evilsoul
Цитата
если я правильно понял, так айпи у тебя совпадают с таблицы traffic и users

trafd_to - по этой колонке надо смотреть (это входящий, исходящий в trafd_from).
Да но не все, к тем что нету в users тоже нужно иметь доступ (чтоб они в вывод могли попадать)
Цитата
и где у тебя столбик HAVING host ='$host' хост?

столбик host - символическая ссылка яж обьяснял вроде.

Спустя 9 минут, 12 секунд (28.01.2011 - 12:10) linker написал(а):
ip2long()
long2ip()

Спустя 2 минуты, 44 секунды (28.01.2011 - 12:13) Evilsoul написал(а):
блин, извини, но не могу задачу понять.
тебе нужно вытащить строку из таблицы traffic и строку из таблицы users где их айпи совпадают и + ко всему этому вытащить всю таблицу users. Так?

Спустя 33 минуты, 17 секунд (28.01.2011 - 12:46) Renden написал(а):
linker
Спасибо, почитаю.
Evilsoul
Цитата

тебе нужно вытащить строку из таблицы traffic и строку из таблицы users где их айпи совпадают и + ко всему этому вытащить всю таблицу users. Так?

почти, тока заместо users надо вытащить всю таблицу traffic. Мой запрос рабочий, меня неустраивает время этого запроса.
Еще раз:
Я вытаскиваю имя юзера если оно совпадает с users.ip=traffic.trafd_to, если несовпадает то вытаскиваю просто айпи из traffic.trafd_to.

Спустя 26 минут, 17 секунд (28.01.2011 - 13:13) Renden написал(а):
Покурив документацию к mysql выкурил что:
Цитата

Выражение HAVING может ссылаться на любой столбец или псевдоним, упомянутый в выражении select_expression. HAVING отрабатывается последним, непосредственно перед отсылкой данных клиенту, и без какой бы то ни было оптимизации. Не используйте это выражение для определения того, что должно быть определено в WHERE.

Придеться в запросе использовать только ip и where раз having и ссылки полное УГ( Нде..
Ладно закрывайте, всем спс за участие)

Спустя 1 час, 24 секунды (28.01.2011 - 14:13) Evilsoul написал(а):
Renden
так тебе хевен и не нужен, вообще ко мне наконец дошло что тебе нужно.
если ты пытаешься всем айпи у которых есть сходство прицепить имя юзера, то только через джоин, но есть ещё вариант, можно сделать два запроса и построить таблицу на ПШП, так быстрее всего будет
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.