Оптимус Пьян: даже для 3 млн это долго. А какое окружение? Это виртуальная машина? Какие еще службы работают на сервере, например файловый сервер. Какие диски и сколько пямяти?
Борис Животное: Нормальное решение, только вот, как я уже заметил, глобальные временные таблицы лучше заменить на обычные или табличную переменную. Можно ещё оформить всё это как процедуру и в коде вызывать ее. Но это уже дело вкуса и политики разработки.
Уберите лишнее из кода: первичный ключ на временной таблице, хинты на update.
Не хватает обработчика ошибок, который будет откатывать транзакцию. Предполагаю, что он есть в коде на C#, но тем не менее
> Это по какой причине? Как вообще значение REPLICATED влияет на возвращаемый запросом результат? Борис Животное: а вы сделайте индекс по REPLICATED, и тогда данные могут выбираться из этого индекса. А поскольку вы его обновили первым апдейтом, то повторная выборка вернёт уже другие данные.
Вы конечно можете сказать, что никто не будет добавлять такой индекс. Но как вы сможете это гарантировать? В общем случае бизнес-логика не должна зависеть от наличия отсутствия индексов.
Насчет вашего решения ниже: вы правильно сделали, что сначала сохранили обновляемые ID, но для этой задачи вам не нужны глобальные временные таблицы, достаточно было бы и обычных - локальных
Я бы дополнил ответ Сергея: после этого надо создать линки Загрузка, Видео, Музыка на примонтированном HDD
то есть например: монтируем весь HDD в /home/user/hdd
создаём симлинк: $ ln -s hdd/music Музыка
и то же для Загрузка и Видео
У вас он вообще не должен вывести данные, так как у вас там ошибка синтаксиса, а именно не хватает группировки по id, name и time. А чтобы он заработал как хотите, то надо в select оставить idUsr и date(time), тоже и group by. А в where ставить анализируемый период: например time >= '2016-08-01' and time < '2016-09-01'
Кстати ниже тоже рабочее решение через join с той же таблицей
> Проблема состоит в том, что она длинее 256 символов
Вы уверены, что проблема в длине строки? Попробуйте в лоб:
$signFromPost = base64_decode($params['sign']).
Максим Федоров: мне кажется вы преувеличиваете затраты на join. К тому же присоединять календарь надо к результирующему набору. А это не настолько затратно. Зато такая таблица решает множество проблем.
NOINIT c DIFFERENTIAL никак не пересекаются.
Читать хабр, конечно хорошо, но в вашем случае оф. документация незаменима.
Собственно вопроса в вашем сообщении нет.
Alex: Но при этом ньюанс, если в таблице не существует записи полностью удовлетворяющей условию, то выберется та, у которой больше атрибутов заполнено (такой своеобразный best match). В нашем примере их всегда 3. Но ведь key-value таблицы делают не для того, чтобы хранить 3 атрибута.
Вобщем твое решение, если оно реально быстрее, можно использовать, но при этом надо понимать его оганичения.
PS. Сделаешь тест, поделись :)
на "ты" проще, но если с этим проблемы, скажи.
ты немного фиксирован на тестовом наборе записей. На нём твой запрос отрабатывает правильно, но если там появляется запись, где совпадают не все условия, то они тоже попадают в выборку.
Ошибка вот в этой мысли: " Что мы имеем:
по каждому из условий вернутся строчки с id продукта, только для одних, их будет больше, для других меньше (чем больше id продукта, тем выше совпадение с условиями). ."
На самом деле вернутся все записи где совпало хотя бы одно условие благодаря упомянутому неправильному использованию OR. И если следовать логике этого запроса, то надо результат отсортировать по count(*) desc и выбрать только первую запись.
Пока писал, понял как заставить такой запрос работать:
Надо в having (count(*)) ставить количество условий, т.е. having (count(*)) =3
При этом надо быть увереным, что в таблице нет дублирующихся записей, например (Значение = 200 and Idатрибута = 2 ) пять раз.
тогда все будет правильно и возможно даже быстрее моего решения, так как у меня по сути 3 запроса.
Но тут надо уже планы смотреть.