либо повышать точность времени, либо принять, что с одинаковым временем более поздний платеж с бОльшим id. Мой запрос, удовлетворяющий этому условию, ниже вашего)
SELECT p.uid, p.amount
FROM payments p
JOIN
(SELECT uid, MAX(pay_date*1000000 + id) AS max_dt
FROM payments
GROUP BY uid) sel ON p.uid = sel.uid
AND (p.pay_date*1000000 + p.id) = sel.max_dt;
Думаю план у него будет плохим, да и 1000000 надо заменить на «очень большое значение». Короче, просто такой себе вариант
ну так авторизуется он же по логину/паролю, дальше получает сессию и выборка идет по нет. Если говорить об оптимизации, то сессию можно сделать из двух частей: id юзера и самой сессии, выборку делать по id и проверять сессию. Но сам запрос выше совершенно часто встречается
Ну я понял, mssql использует бинарный протокол и при этом еще и _параллельно_ парсит и конвертит запросы с плейсхолдерами в одну строку. Двойная работа.
А еще мне понравилось ваше высказывание, что раз IN(..) редко используется, значит и проблемы нет. Вы понимаете, что если хотя бы раз оно используется, то уже надо что-то делать чтоб заменить плейсхолдеры?
return тоже «смахивает» на goto, но его никто в этом не упрекает. Есть четкий блок, внутри него условия, несовпадение условий — выход из блока. Если внимательно присмотритесь, то выход из блока используется сплошь и рядом: досрочное завершение подпрограммы с return, досрочный выход из цикла, case, иксепшины и т.д. Это нормальный прием. Сейчас объясню почему. Обычно, логика выполнения идет по одному пути: проверка, не выполнилась — свалили, проверка, не выполнилась — свалили, и т.д. Так происходит очень часто.
Например, банальная ситуация: проверили существование отправителя, нет — ошибка и конец, проверили достаточность денег на счету, нет — ошибка и коней, с получаетелем тоже самое и в конце запись в таблицу логов, нет — ошибка и конец. Если вы будете делать это через if, то создадите многоэтажную конструкцию, на 4й ступеньке ваш код перейдет в стадию «отвратный». Я практически никогда не допускаю больше 3х вложенностей.
Если же представить выполнение задачи по моему методу, то будет примерно следующее:
ok = 0;
{
проверка1 or last;
вычисления;
проверка2 or last;
вычисления;
проверка3 or last;
вычисления;
проверка4 or last;
ok = 1;
}
ok or rollback;
В такой конструкции явно прослеживается корректная цепочка операций, а все что не удовлетворяет ей — отсекается. Попробуйте, так очень удобно и понятно
Я пользуюсь еще интересным приемом (правда это немножко иной язык программирования: perl):
{
a == b or last;
d > x + 150 or last;
f < 16 or last;
# все условия выполнены, выполняем действие
…
}
Он показал саму суть: раз уж добавлять лишние скобки, то до конца — ведь в 1м примере голосовалки все равно может быть неоднозначное восприятие. Многим приходится программировать на разных языках и там приоритет операций может быть иным, так что перестраховщики будут ставить скобку после каждой операции
В шарпе будет медленнее та как строки неизменяемые. А вот, скажем, в перле будет быстрее конкатенация, я даже проверил это (больше чем в 2 раза быстрее, хотя зависит от конкретики), поскольку там именно такой алгоритм выделения памяти, средства языка позволяют это проверить даже, и я проверял. Если в какой-то реализации и/или языке конкатенация будет быстрее — это ли не доказательство, что ее иногда целесообразней использовать?
не может быть работы с массивом быстрее работы со строкой в принципе: скриптовые языки выделяют память под строку с запасом, в процессе может увеличиваться тоже с запасом, каждая итерация конкатенации к текущей строке делается гораздо быстрее чем обращение к элементу массива, поскольку не надо выделять память, просто копи несколько байт и все.
по http ходят-то не массивы и объекты, а строки. В любом случае, на клиентской стороне будет какой-то парсер. Например, json. Либо же, если не требуется сложной логики: приходит строка с числами через запятую — она же, вуаля, и интерпретируется как массив. Посмотрите внимательно мое первое сообщение: я говорю о методе формировании этой строки на серверной стороне.
т.е вы приводите пример, с которым я-то и не спорю (join массива), а другие видеть не хотите, потому что у вас таких задач нет? А у меня недавно была задача. Нужно было на ajax запрос дать ответ: куча координат, разделенных запятой. В серверной части я посчитал нерациональным сначала получить массив координат, а потом джойнить их через запятую т.к. массив тут явно лишнее звено. Я просто сделал $result .= "$x,$y,"; и после цикла chop $result (убрал последнюю запятую). Получилось очень просто и удобочитаемо. Сереьрянной пули, как вы понимате, не существует в программировании. Имеют права на существование разные подходы
так, именно, метод «без join» позволяет не использовать массив, а обращение к элементу массива — слабое звено. Так что пример не в тему. Я совсем не против join (было бы глупо спорить против такого полезного оператора), но очевидно, что есть ситуации, когда эффективней будет конкатенация. Если пойдет жесткий спор, придется и мне приводить примеры и тесты
Думаю план у него будет плохим, да и 1000000 надо заменить на «очень большое значение». Короче, просто такой себе вариант
А еще мне понравилось ваше высказывание, что раз IN(..) редко используется, значит и проблемы нет. Вы понимаете, что если хотя бы раз оно используется, то уже надо что-то делать чтоб заменить плейсхолдеры?
Например, банальная ситуация: проверили существование отправителя, нет — ошибка и конец, проверили достаточность денег на счету, нет — ошибка и коней, с получаетелем тоже самое и в конце запись в таблицу логов, нет — ошибка и конец. Если вы будете делать это через if, то создадите многоэтажную конструкцию, на 4й ступеньке ваш код перейдет в стадию «отвратный». Я практически никогда не допускаю больше 3х вложенностей.
Если же представить выполнение задачи по моему методу, то будет примерно следующее:
ok = 0;
{
проверка1 or last;
вычисления;
проверка2 or last;
вычисления;
проверка3 or last;
вычисления;
проверка4 or last;
ok = 1;
}
ok or rollback;
В такой конструкции явно прослеживается корректная цепочка операций, а все что не удовлетворяет ей — отсекается. Попробуйте, так очень удобно и понятно
{
a == b or last;
d > x + 150 or last;
f < 16 or last;
# все условия выполнены, выполняем действие
…
}