|
|
|
|
|
для: Trianon
(12.04.2010 в 23:43)
| | к сожалению, "кроме ключа" нужно. Про конструктор запроса я не спрашивал, так написать его не сложно. Главное знать, какой запрос он должен формировать. EXPLAIN и BENCHMARK должны применяться на реальных данных, коих должно быть достаточно много и кои должны быть различны. На 10 наскоро набитых записях общие выводы не сделаешь. Поэтому, тут больше обращение к вашему практическому опыту. Я изложил свои аргументы. Возможно 10 мелких выборок будут происходить дольше, чем одна крупная. Но при БОЛЬШОЙ базе и большем количестве условий (ни 2, ни 10, а, к примеру, 50), такая выборка сожрет много ресурсов. Если это еще и часто будет происходить... думаю, тормоза серверу обеспечены.
Это мое мнение. Оно основано не на конкретном опыте и не на теории, относящейся к конкретному случаю. Оно основано на общих наблюдениях: если сгребать все бульдозером, получится громоздким, медленным и ресурсоемким.
Кстати, для "или", сравнивающего одно и то же поле, лучше FIND_IN_SET(vid,"1,2,3"), чем vid=1 OR vid=2 OR vid=3. Да и конструктор такой сделать легче (просто превратить массив в строку, разделенную запятыми: implode(",", $_GET['vid']) - и вся кнструкция). Но поскольку изначально задача стояла именно в коструировании для "и", FIND_IN_SET для примера не сразу пришло в голову. Просто думал о том, что vid=1 AND vid=2 AND vid=3, в отличие от vid=1 OR vid=2 OR vid=3 не будет работать. Поэтому соорудил конструктор для vid=1 OR vid=2 OR vid=3, чтобы показать, что это не фиксированный запрос, а запрос, который набирается в зависимости от условий. | |
|
|
|
|
|
|
|
для: kosta_in_net
(12.04.2010 в 23:06)
| | в принципе, если ничего кроме ключа не нужно, можете попробовать и без основной.
SELECT DISTINCT l1.id
FROM link l1
JOIN link l2 ON m.id = l2.id AND l2.vid = 'другое значение'
WHERE l1.vid = 'одно значение'
|
На счет того, какой быстрее - так есть EXPLAIN и BENCHMARK
Я загадывать не буду. Тем более что задачу решал при явной неполноте условия.
Относительно конструирования запроса по данным из формы - тут уж извините, коней на переправе не меняют.
Если Вы хотели выяснять этот момент, то так бы проблему и описывали. | |
|
|
|
|
|
|
|
для: Trianon
(12.04.2010 в 21:53)
| | я предполагал такой вариант. Есть только 1 проблема: вариантов типа 'одно значение' может быть с пол сотни, а может не быть ни одного... К примеру, поиск людей, живущих в Москве, имеющих высшее образование и работающих по строительной специальности (3 условия должны совпасть одновременно)... но если ограничения в форме поиска не поставлены, то значит не делать джонов... В то же время, ограничений может быть и пол сотни. С условием OR все просто:
if(@$_GET['vid']){
foreach($_GET['vid'] AS $value){
if(@$linkwhere){
$linkwhere.=' OR ';
}
@$linkwhere.='vid='.$value;
}
if(@$where){
$where.=' AND ('.$linkwhere.')';
}else{
$where=$linkwhere;
}
}
| где:
$_GET['vid'] - вероятный массив ограничений.
$where - другие параметры выборки (как раз для main-таблицы)
И таблица джоница к основной
Сейчас соорудил такой конструктор запроса:
if(@$_GET['vid']){
foreach($_GET['vid'] AS $value){
if(@$subsql){
$subsql=' SELECT id FROM '.link.' WHERE vid='.$value.' AND id IN ('.$subsql.')';
}else{
$subsql=' SELECT id FROM '.link.' WHERE vid='.$value;
}
}
if(@$where){
$where.=' AND id IN ('.$subsql.')';
}else{
$where=' id IN ('.$subsql.')';
}
}
|
Джонить таблицы не приходится.
Вроде работает (неуверенность вызывается недостатком опыта). Хотелось бы узнать мнение столь опытного человека, как Трианон. Какой вариант оптимальней? Ваш, или мой? Ваш сконструировать легче. Но, насколько я понимаю, для вашего создается здоровенный массив данных, обединяющий основную таблицу и множество копий вспомогательной. А в моем варианте происходит несколько небольших последовательных выборок, каждая из которых уточняет предыдущую, никакого гигантсгого массива не формируется, так как ничего не джонится. Я правильно понимаю ситуацию? Какой метод в итоге лучший? | |
|
|
|
|
|
|
|
для: kosta_in_net
(12.04.2010 в 21:48)
| | для начала нужно опереться на ту таблицу, которая поставляет первичный ключ к чужому link.id
SELECT m.id
FROM main m
JOIN link l1 ON m.id = l1.id AND l1.vid = 'одно значение'
JOIN link l2 ON m.id = l2.id AND l2.vid = 'другое значение'
|
| |
|
|
|
|
|
|
| Таблица со структурой:
CREATE TABLE IF NOT EXISTS `link` (
`id` int(11) unsigned NOT NULL,
`vid` smallint(6) unsigned NOT NULL DEFAULT '0',
KEY `vid` (`vid`),
KEY `id` (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251;
id - это НЕ уникальный идентификатор записи. Это идентификатор записи в другой таблице, по которому они связываются, но это сейчас не имеет значения. В таблице может быть много записей с одинаковым id, но разным vid. Нужно выбрать такие id, в токорых vid имеет значение и 'одно значение', и 'другое значение'.
Как это сделать? | |
|
|
|
|