Ru-MaNGOS

Вернуться   Ru-MaNGOS > Флуд > Флудильня

Важная информация

Флудильня Разговоры на любые темы.

Мы устаем постоянно работать. Иногда надо где-то немного отдохнуть. Пожалуйста, не надо здесь устраивать бардак.

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
Старый 23.10.2010, 02:14   #1
DiffuSer
Ученый
 
Аватар для DiffuSer
 
Регистрация: 07.03.2010
Сообщений: 131
Сказал(а) спасибо: 9
Поблагодарили 10 раз(а) в 10 сообщениях
DiffuSer На верном пути
По умолчанию JOIN таблиц, как написать

Как исключить из выдачи запроса SELECT * FROM `characters` персонажей на GM-аккаунтах?
DiffuSer вне форума   Ответить с цитированием
Старый 23.10.2010, 03:05   #2
tempura
Forum bot
 
Аватар для tempura
 
Регистрация: 01.02.2010
Адрес: пусто
Сообщений: 841
Сказал(а) спасибо: 286
Поблагодарили 418 раз(а) в 190 сообщениях
Записей в дневнике: 60
tempura отключил(а) отображение уровня репутации
По умолчанию

без join-ов всяких...
Код:
SELECT * FROM `characters`.`characters` WHERE `account` NOT IN 
(SELECT `id` FROM `realmd`.`account` WHERE `gmlevel` !=0);
__________________
Совершенно безопасен для людей, обладающих хотя бы некоторыми минимальными зачатками интеллекта, и способными строить причинно-следственные цепочки.
tempura вне форума   Ответить с цитированием
Старый 23.10.2010, 03:25   #3
DiffuSer
Ученый
 
Аватар для DiffuSer
 
Регистрация: 07.03.2010
Сообщений: 131
Сказал(а) спасибо: 9
Поблагодарили 10 раз(а) в 10 сообщениях
DiffuSer На верном пути
По умолчанию

Благодарю.
DiffuSer вне форума   Ответить с цитированием
Старый 23.10.2010, 10:45   #4
Konctantin
RuDB Dev
 
Аватар для Konctantin
 
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
Konctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всем
По умолчанию

а можно и с джойнами
Код:
SELECT c.*, a.*
FROM `characters`.`characters` c 
LEFT JOIN `realmd`.`account` a
ON a.id = c.guid && a.gmlevel = 0;
__________________
Konctantin вне форума   Ответить с цитированием
Старый 23.10.2010, 13:53   #5
virusav
Администратор
 
Аватар для virusav
 
Регистрация: 19.02.2010
Сообщений: 492
Сказал(а) спасибо: 55
Поблагодарили 341 раз(а) в 154 сообщениях
virusav Реально хороший человекvirusav Реально хороший человекvirusav Реально хороший человекvirusav Реально хороший человек
Отправить сообщение для virusav с помощью ICQ
По умолчанию

LEFT JOIN тут не нужен вообще, обычный перекрестный запрос на выборку данных.
virusav вне форума   Ответить с цитированием
Старый 23.10.2010, 14:02   #6
LordJZ
Супер-модератор
 
Аватар для LordJZ
 
Регистрация: 07.03.2010
Сообщений: 647
Сказал(а) спасибо: 100
Поблагодарили 252 раз(а) в 123 сообщениях
LordJZ Как самоцвет среди гранитаLordJZ Как самоцвет среди гранитаLordJZ Как самоцвет среди гранита
По умолчанию

Цитата:
Сообщение от tempura Посмотреть сообщение
без join-ов всяких...
Код:
SELECT * FROM `characters`.`characters` WHERE `account` NOT IN 
(SELECT `id` FROM `realmd`.`account` WHERE `gmlevel` !=0);
И будет он для каждого ряда из characters выполнять запрос в realmd.account.
Цитата:
Сообщение от Konctantin Посмотреть сообщение
а можно и с джойнами
Код:
SELECT c.*, a.*
FROM `characters`.`characters` c 
LEFT JOIN `realmd`.`account` a
ON a.id = c.guid && a.gmlevel = 0;
Если исправить ошибки в запросе, то он вернет всех персонажей, и для некоторых — их аккаунты.

Наиболее адекватный на мой взгляд запрос:
Код:
SELECT c.* FROM characters.characters c, realmd.account a WHERE c.account = a.id AND a.gmlevel = 0 LIMIT X;
Можете меня поправить.
LordJZ вне форума   Ответить с цитированием
Старый 23.10.2010, 21:28   #7
Deamon
WowCore Dev
 
Регистрация: 11.03.2010
Сообщений: 112
Сказал(а) спасибо: 10
Поблагодарили 51 раз(а) в 25 сообщениях
Deamon Скоро придёт к известности
По умолчанию

Цитата:
Сообщение от LordJZ Посмотреть сообщение
Наиболее адекватный на мой взгляд запрос:
Код:
SELECT c.* FROM characters.characters c, realmd.account a WHERE c.account = a.id AND a.gmlevel = 0 LIMIT X;
Можете меня поправить.
Такой запрос скорее всего сделает декартово произведеие таблиц characters и realmd, а только потом из полученного венегрета будет выбирать записи, удовлетворяющие условию where.

ИМХО, самым адекватным будет немного переделанный вариант того, что предложил Константин
Код:
SELECT c.*
FROM `realmd`.`account` a
LEFT JOIN `characters`.`characters` c ON c.account = a.id
where a.gmlevel = 0;
Набор данных в таблице account по определению меньше, чем набор данных из таблицы characters. Этот запрос сначала сделает выборку всех гмских акков из таблицы account, а затем left join'ом присоединит к ним персонажей из соответствующей таблицы.

Единственная неприятность, которая здесь есть - как из таблицы characters так и из таблицы account будут производится неиндексированные чтения, т.к. не задействуется ни primary key, ни secondary key(если они вообще есть). На малых массивах данных - это значения играть не будет. Но если скажем база персонажей разрастется до 1-го ляма - тогда начнут быть видны проблемы.
Deamon вне форума   Ответить с цитированием
Старый 23.10.2010, 21:37   #8
Lordronn
Умный
 
Регистрация: 17.06.2010
Сообщений: 397
Сказал(а) спасибо: 58
Поблагодарили 55 раз(а) в 38 сообщениях
Lordronn Скоро придёт к известности
По умолчанию

Какой запрос пройдет быстрее, обычный перекрестный, или тот, который предложил Константин?
Lordronn вне форума   Ответить с цитированием
Старый 23.10.2010, 21:41   #9
LordJZ
Супер-модератор
 
Аватар для LordJZ
 
Регистрация: 07.03.2010
Сообщений: 647
Сказал(а) спасибо: 100
Поблагодарили 252 раз(а) в 123 сообщениях
LordJZ Как самоцвет среди гранитаLordJZ Как самоцвет среди гранитаLordJZ Как самоцвет среди гранита
По умолчанию

Цитата:
Сообщение от Deamon Посмотреть сообщение
Такой запрос скорее всего сделает декартово произведеие таблиц characters и realmd, а только потом из полученного венегрета будет выбирать записи, удовлетворяющие условию where.

ИМХО, самым адекватным будет немного переделанный вариант того, что предложил Константин
Код:
SELECT c.*
FROM `realmd`.`account` a
LEFT JOIN `characters`.`characters` c ON c.account = a.id
where a.gmlevel = 0;
Набор данных в таблице account по определению меньше, чем набор данных из таблицы characters. Этот запрос сначала сделает выборку всех гмских акков из таблицы account, а затем left join'ом присоединит к ним персонажей из соответствующей таблицы.

Единственная неприятность, которая здесь есть - как из таблицы characters так и из таблицы account будут производится неиндексированные чтения, т.к. не задействуется ни primary key, ни secondary key(если они вообще есть). На малых массивах данных - это значения играть не будет. Но если скажем база персонажей разрастется до 1-го ляма - тогда начнут быть видны проблемы.
На 90 тыс. персонажей и 60 тыс. аккаунтов мой запрос работает в полтора раза быстрее вашего, и почти в 3 раза быстрее tempura-вского.

Добавлено: правда, у меня почти полностью закеширована account.
Цитата:
Сообщение от Lordronn Посмотреть сообщение
Какой запрос пройдет быстрее, обычный перекрестный, или тот, который предложил Константин?
Запрос от Konctantin некорректен, неужели выше я выразился настолько неясно?
LordJZ вне форума   Ответить с цитированием
Старый 23.10.2010, 21:43   #10
virusav
Администратор
 
Аватар для virusav
 
Регистрация: 19.02.2010
Сообщений: 492
Сказал(а) спасибо: 55
Поблагодарили 341 раз(а) в 154 сообщениях
virusav Реально хороший человекvirusav Реально хороший человекvirusav Реально хороший человекvirusav Реально хороший человек
Отправить сообщение для virusav с помощью ICQ
По умолчанию

Лорд, проверь этот запрос у себя на скорость.
Код:
SELECT
	`characters`.*
FROM
	`characters`.`characters`, `realmd`.`account`
WHERE
	`characters`.`account`=`account`.`id`
	AND `account`.`gmlevel`=0
ORDER BY
	NULL;
virusav вне форума   Ответить с цитированием
Старый 23.10.2010, 21:45   #11
LordJZ
Супер-модератор
 
Аватар для LordJZ
 
Регистрация: 07.03.2010
Сообщений: 647
Сказал(а) спасибо: 100
Поблагодарили 252 раз(а) в 123 сообщениях
LordJZ Как самоцвет среди гранитаLordJZ Как самоцвет среди гранитаLordJZ Как самоцвет среди гранита
По умолчанию

Цитата:
Сообщение от virusav Посмотреть сообщение
Лорд, проверь этот запрос у себя на скорость.
Код:
SELECT
	`characters`.*
FROM
	`characters`.`characters`, `realmd`.`account`
WHERE
	`characters`.`account`=`account`.`id`
	AND `account`.`gmlevel`=0
ORDER BY
	NULL;
Практически тоже самое, что и у Deamon-а. 93 мс против 94 мс. (может сказалось кеширование)
LordJZ вне форума   Ответить с цитированием
Старый 23.10.2010, 21:57   #12
virusav
Администратор
 
Аватар для virusav
 
Регистрация: 19.02.2010
Сообщений: 492
Сказал(а) спасибо: 55
Поблагодарили 341 раз(а) в 154 сообщениях
virusav Реально хороший человекvirusav Реально хороший человекvirusav Реально хороший человекvirusav Реально хороший человек
Отправить сообщение для virusav с помощью ICQ
По умолчанию

Обязательно.
Первый раз выполняешь запрос, далее уже из кеша вызывается.

Мой запрос выбирал 1425 записей из таблицы персов и одну из аккаунтов.
Запрос Deamon - 1288 из таблицы персов и две из аккаунтов.

Ключи и количество записей можно смотреть командой EXPLAIN перед запросом.
ORDER BY NULL позволяет принудительно убрать сортировку при запросе на выборку, даже если сам запрос не содержит ORDER BY.
Очень помогает при выборе большого количества данных, когда сортировка не имеет значения.
EXPLAIN позволяет видеть, когда в запрос добавляется сортировка.
virusav вне форума   Ответить с цитированием
Старый 23.10.2010, 23:28   #13
LordJZ
Супер-модератор
 
Аватар для LordJZ
 
Регистрация: 07.03.2010
Сообщений: 647
Сказал(а) спасибо: 100
Поблагодарили 252 раз(а) в 123 сообщениях
LordJZ Как самоцвет среди гранитаLordJZ Как самоцвет среди гранитаLordJZ Как самоцвет среди гранита
По умолчанию

characters не кешируется, это же живой сервер.
LordJZ вне форума   Ответить с цитированием
Старый 23.10.2010, 23:32   #14
DiffuSer
Ученый
 
Аватар для DiffuSer
 
Регистрация: 07.03.2010
Сообщений: 131
Сказал(а) спасибо: 9
Поблагодарили 10 раз(а) в 10 сообщениях
DiffuSer На верном пути
По умолчанию

Всё, спасибо, разобрался.
DiffuSer вне форума   Ответить с цитированием
Ответ


Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.



Текущее время: 16:49. Часовой пояс GMT +3.


ru-mangos.ru - Русское сообщество MaNGOS
Главная цель проекта MaNGOS - обучающая, поэтому разрешается использовать исходный код и собранную программу только для образовательных целей.
Вы не можете использовать MaNGOS в коммерческих целях, а также не разрешается устанавливать публичные серверы на базе MaNGOS.
Любое копирование материалов, информации в любом виде без указания источника - форума Ru-MaNGOS будет считаться нарушением авторских прав и нарушением Уголовного Кодекса РФ, ст. 146 ст. 147.
Перевод vBulletin: zCarot