|
Оптимальный JOIN запрос
|
|||
---|---|---|---|
#18+
Задача такая. На сервер поступают данные типа: productId userId time group1 colums list group2 colums list Колонки группы 1 меняются редко, поэтому возникла идея разбить данные на 2 таблицы и в первую добавлять записи только тогда, когда они меняются. Во вторую таблицу идут статистические данные, которые меняются и вставляются при каждом поступлении данных: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
Нужно создать запрос или лучше представление (view), которое даст возможность рассматривать 2 таблицы как одну целую, типа: Код: plsql 1. 2. 3. 4. 5.
Нужно продолжить условие JOIN, чтобы в результате строки, где table1.time = 1 соединились со строками table2.time = 1,2,3 table1.time = 4 соединились со строками table2.time = 4,5,6,7 table1.time = 8 соединились со строками table2.time = 8 table1.time = 9 соединились со строками table2.time = 9 и т.п. Как это можно оптимальнее написать? Благодарю! -- С уважением, Алексей. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2018, 00:43 |
|
Оптимальный JOIN запрос
|
|||
---|---|---|---|
#18+
table1.time <= table2.time - совершенно лишнее (table1.time = table2.time) or (table1.time = 4 and inlist(table2.time,4,5,6,7)) ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2018, 02:19 |
|
Оптимальный JOIN запрос
|
|||
---|---|---|---|
#18+
сорри (table1.time = table2.time) or (table1.time = 4 and (table2.time IN(4,5,6,7))) ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2018, 02:22 |
|
Оптимальный JOIN запрос
|
|||
---|---|---|---|
#18+
982183, это смешно. Данные приведены для примера, я не знаю какие они будут и какое будет время. Если условие будет table1.time <= table2.time, то строки table2.time = 4..7 соединятся с table2.time = 1 и 4, А нужно только с 4-й. Поэтому условие нужно ограничить как-то: Код: sql 1.
чтобы 1-я строка не включалась. Соответственно, для 8-й строки из 2 таблицы нужно отфильтровать 1-ю и 4-ю из 1-й. Для 9-й строки из 2 таблицы нужно отфильтровать 1-ю, 4-ю и 8-ю из 1-й и смержить только с 9-й. Все строки из 2-й таблицы больше 9-й нужно смержить только с 9-й строкой из 1-й таблицы. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2018, 02:38 |
|
Оптимальный JOIN запрос
|
|||
---|---|---|---|
#18+
Правда можно тупо сделать: добавить во 2-ю таблицу колонку table1_time и при вставке записей заполнять её для JOIN-a значением: Код: sql 1.
Но хочется сделать покрасивше с JOIN-ом. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2018, 02:45 |
|
Оптимальный JOIN запрос
|
|||
---|---|---|---|
#18+
Ну так задачу ставить надо правильно. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2018, 03:01 |
|
Оптимальный JOIN запрос
|
|||
---|---|---|---|
#18+
С ходу могу предложить завести таблицу связей time1, time2 time1 = max(table1.time) with table1.time <= table2.time ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2018, 03:31 |
|
Оптимальный JOIN запрос
|
|||
---|---|---|---|
#18+
или применить CROSS APPLY С ним будет "оптимальней" ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2018, 05:41 |
|
Оптимальный JOIN запрос
|
|||
---|---|---|---|
#18+
Схематично так: SELECT table2.time, table1.* FROM table2 CROSS APPLY (SELECT max(table1.time) FROM table1 WHERE table1.time <= table2.time ) ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2018, 05:46 |
|
Оптимальный JOIN запрос
|
|||
---|---|---|---|
#18+
Aleksey K, при помощи LEAD получать в первой таблице следующее за текущим время, джойн делать between-у ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2018, 06:12 |
|
Оптимальный JOIN запрос
|
|||
---|---|---|---|
#18+
Щукина АннаAleksey K, при помощи LEAD получать в первой таблице следующее за текущим время, джойн делать between-уСхематично как-то так: <=== Кликни тут - оно откроется... Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41.
... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2018, 06:44 |
|
Оптимальный JOIN запрос
|
|||
---|---|---|---|
#18+
Aleksey K, Не рассматривали идею просто хранить в table2 ссылку на запись из table1, актуальную на момент сохранения? join в этом случае будет элементарным. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2018, 12:15 |
|
Оптимальный JOIN запрос
|
|||
---|---|---|---|
#18+
Aleksey K, если для мелких выборок, в кач-ве заместителя полноджойна с оконными (щукина) такое вью : Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.
не вычитывал, для больших видимо оконное. думается дешевле апдейтить тебл1 в момент прихода отсечки . ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2018, 16:28 |
|
Оптимальный JOIN запрос
|
|||
---|---|---|---|
#18+
qwwqдумается дешевле апдейтить тебл1 в момент прихода отсечки . Выборки потом будут крупные. Уже добавил колонку во 2-ю таблицу - так и буду делать - проще всего. Спасибо! Внешний ключ на 3 колонки добавил. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2018, 16:55 |
|
Оптимальный JOIN запрос
|
|||
---|---|---|---|
#18+
Aleksey Kqwwqдумается дешевле апдейтить тебл1 в момент прихода отсечки . Выборки потом будут крупные. Уже добавил колонку во 2-ю таблицу - так и буду делать - проще всего. Спасибо! Внешний ключ на 3 колонки добавил. для хешджойна фк не нужен и индекс (на большой таблице) скорее вреден. если она реально большая. добавьте поле в 1-ю (короткую таблу) и попробуйте индекс на ренджи. (range от двух таймов) если разница мощностей порядки -- д.б. не хуже. хотя и так неплохо. а если основной поиск идет по неуказанным полям 1--й -- ваше решение скорее верное, чем нет. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.06.2018, 13:59 |
|
|
start [/forum/topic.php?fid=53&msg=39662764&tid=1995717]: |
0ms |
get settings: |
11ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
44ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
57ms |
get tp. blocked users: |
1ms |
others: | 287ms |
total: | 437ms |
0 / 0 |