• Познакомьтесь с пентестом веб-приложений на практике в нашем новом бесплатном курсе

    «Анализ защищенности веб-приложений»

    🔥 Записаться бесплатно!

  • CTF с учебными материалами Codeby Games

    Обучение кибербезопасности в игровой форме. Более 200 заданий по Active Directory, OSINT, PWN, Веб, Стеганографии, Реверс-инжинирингу, Форензике и Криптографии. Школа CTF с бесплатными курсами по всем категориям.

Выборка объемных данных

  • Автор темы DeMx
  • Дата начала
Статус
Закрыто для дальнейших ответов.
D

DeMx

Есть много-много записей (50 тысяч сейчас и в будущем, возможно,
больше) в двух таблицах и нужно проводить из них выборки (с поиском по
некоторым полям).

Вопрос в том, как это сделать быстрее? Полностью средствами мускула
или же все же PHP, по старинке - в цикле.

Под средствами MySQL я подразумеваю выборку данных с помощью "JOIN",
либо: "table1 AS t1, table2 AS t2".

Средства PHP: юерем все данные из первой таблицы, затем из второй.
После чего проводим необходимые операции в цикле, "скрещивая" данные.

Я это к тому, что средствами MySQL никак не могу получить достойную
скорость. Возможно дело и в сервере, но все же...

Хотелось бы почитать замечания из личного опыта по данному вопросу. <_<
 
?

????

только средствами самого SQL сервера. Обработка 50.000 записей должна происходить даже на слабеньком сервере не больше чем за 1-5 сек.
 
E

European

Никогда не работал ни с MySQL, ни с PHP, но любой сервер БД разрабатывается и оптимизируется под работу с НАБОРАМИ данных, поэтому однозначно стоит работать средствами MySQL. А вопрос быстродействия нужно рассматривать отдельно.
 
D

DeMx

Я это веду к тому, что вот такой запрос:
Код:
SELECT 
m.url, 
m.login, 
m.comment, 
COUNT(DISTINCT m.login) AS num_access, 
e.email 
FROM 
filter2_main AS m 
LEFT JOIN filter2_email AS e ON m.login = e.email OR m.id = e.id 
GROUP BY 
m.url
никак не могу выполнить. Сервер вообще ответ не возвращает... Я даже полчаса ждал. )
 
E

European

Ну в таких случаях лучше использовать профайлеры запросов и по ним разбираться где проблема в конкретном запросе. В данном запросе попробуй поменять
Код:
LEFT JOIN filter2_email AS e ON m.login = e.email OR m.id = e.id
на
Код:
LEFT JOIN filter2_email AS e ON m.login = e.email AND m.id = e.id
Мне кажется что проблема в условии объединения 2-х таблиц
 
D

DeMx

Так нет, мне нужна именно такая логика, с "ИЛИ".

И кстати, это все равно не помогло. :huh:
 
?

????

так сервер данные и не должен вернуть - он должен вернуть ошибку :huh:
 
E

European

<!--QuoteBegin-????+16:11:2006, 08:14 -->
<span class="vbquote">(???? @ 16:11:2006, 08:14 )</span><!--QuoteEBegin-->так сервер данные и не должен вернуть - он должен вернуть ошибку
[snapback]47960" rel="nofollow" target="_blank[/snapback]​
[/quote]
Что-то я прикола не понял? Почему сервер должен вернуть ошибку?
 
D

DeMx

Для: ????
Какую еще ошибку? Этот запрос я проверял на локалхосте с не большими данными - все работает.
Т.е. проблема в том, что на сервере, с более менее большими данными все перестает работать.
 
B

Barmutik

Плохой тон... вернее даже не верно спроектированная БД... делать джойны по строковым полям... отсюда и тормоза...
 
E

European

Согласен... Стоит подумать над нормализацией... Хотя странно, что запрос выполняется так долго
 
D

DeMx

Все это понятно... но надо же как-то выйти из уже сложившейся ситуации. Перепроектировать все нет никакой возможности.
 
E

European

Я так понимаю, что m.login и e.email - строковые поля, а m.id и e.id - числовые. Я бы попробовал в JOIN оставить только числовые поля, а строковые добавить в WHERE. Кроме того, можно попробовать создать индексы, если их еще нет
 
D

DeMx

Для: European
Нет, id - тоже строковое поле, генерируется где-то в скриптах (цифры в перемешку с буквами)
Вот структура вся:
Код:
CREATE TABLE `filter2_main` ( 
`id` char(32) NOT NULL default '', 
`url` char(200) NOT NULL default '', 
`login` char(50) NOT NULL default '', 
`pass` char(50) NOT NULL default '', 
`comment` char(250) default NULL, 
`musage` char(250) default NULL, 
`deleted` int(1) default '0', 
PRIMARY KEY (`id`,`url`,`login`,`pass`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 

CREATE TABLE `filter2_email` ( 
`id` char(32) NOT NULL default '', 
`url` char(200) NOT NULL default '', 
`email` char(50) NOT NULL default '', 
`email_pass` char(50) NOT NULL default '', 
`comment` char(250) default NULL, 
`musage` char(250) default NULL, 
`deleted` int(1) default '0', 
PRIMARY KEY (`id`,`url`,`email`,`email_pass`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
 
E

European

М-да... Если бы у меня была такая база, я бы с работы уволился :) Первичный ключ из 4-х строковых полей меня порадовал :) Попробуй создать индексы для полей, используемых для объединения
 
D

DeMx

Для: European
:)
С индексами я уже прошел... создавал индексы типа full-text для связующих полей - не помогло. Пробовал даже добавить уникальное поле с auto_increment - тоже ничего не дало.
 
E

European

В таком случае я умываю руки :) Лично я бы перепроектировал таблицы! :) Или хотя бы допроектировал
 
D

DeMx

Для: European
Хм... Ну, предположим решил я перепроектировать эти две злосчастные таблицы... Как бы ты предложил сделать? :)
 
E

European

Сначала информацию о пользователе (id, url, login, pass, ... ) сделай отдельной таблицей, где id - первичный ключ (естественно числовой). Если честно, то назначение этих 2 таблиц мне не очень понятно, поэтому давать толковые советы врядли получится
 
B

Barmutik

Соглашусь что глюч по 4-м строкомвым полям ... это большая техническая редкость :).. не принимайте просьба близко к сердцу...

Что бы давать совету по перепроектированию нужно обладать большей информаией что хранится в таблицах и что бы потмо планируете с ними делать...

Хотя я тут для тестов сделал join по стрингам в MS SQL (под рукой).. на 50.000 работает всё только в путь в течении 1 секунды ... хотя конечно у меня нет такой замороченной структуры ...
 
Статус
Закрыто для дальнейших ответов.
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!