Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Порядок вычисления переменных / 19 сообщений из 19, страница 1 из 1
26.05.2015, 16:55:25
    #38968990
mysql_noon
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок вычисления переменных
Добрый день. Читаю в доке следующий абзац
For other statements, such as SELECT, you might get the results you expect, but this is not guaranteed. In the following statement, you might think that MySQL will evaluate @a first and then do an assignment second:

Код: sql
1.
SELECT @a, @a:=@a+1, ...


However, the order of evaluation for expressions involving user variables is undefined.
Я понял так, что никто мне не гарантирует, что сперва покажется значение переменной @a, а затем этой к переменной прибавится ещё единица. Может быть наоборот, сперва прибавление единицы, а потом отображение значения переменной.

Написал тестовый запросик
Код: 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.
SET @prev = '';
SET @grp  = null ;

SELECT t.*
  from (
    select t.*
          ,CASE WHEN IFNULL(@grp, '#') != t.gr
                THEN @prev := null
           END                                as q
          ,@grp := t.gr
          ,CASE when @prev = ''
                then ''
                else STR_TO_DATE(@prev, '%d.%m.%Y')
            end                                             as prev
          ,@prev :=  DATE_FORMAT(t.dd, '%d.%m.%Y')          as dd2
      from (  SELECT t.*
                FROM (  SELECT STR_TO_DATE('01.05.2015', '%d.%m.%Y') as dd,  1 as gr
                        UNION all
                        SELECT STR_TO_DATE('01.06.2015', '%d.%m.%Y') as dd,  1 as gr
                        UNION all
                        SELECT STR_TO_DATE('01.07.2015', '%d.%m.%Y') as dd,  1 as gr
                        UNION all
                        SELECT STR_TO_DATE('02.08.2015', '%d.%m.%Y') as dd,  2 as gr
                        UNION all
                        SELECT STR_TO_DATE('01.09.2015', '%d.%m.%Y') as dd,  1 as gr
                        UNION all
                        SELECT STR_TO_DATE('02.10.2015', '%d.%m.%Y') as dd,  2 as gr
                        UNION all
                        SELECT STR_TO_DATE('01.11.2015', '%d.%m.%Y') as dd,  1 as gr
                    ) t
               ORDER by t.gr
                       ,t.dd
           ) t
       ) t
 ORDER by t.dd
         ,t.gr


Как тогда быть, если нужно сперва отобразить, потом изменить именно в определенном порядке (имитировать аналитические функции) и как быть уверенным, что оптимизатор не перепишет запрос и не начнёт выполнять запрос по другому, не в нужном мне порядке?

Версия 5.5.
...
Рейтинг: 0 / 0
26.05.2015, 17:04:57
    #38969006
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок вычисления переменных
mysql_noonКак тогда быть, если нужно сперва отобразить, потом изменить именно в определенном порядке (имитировать аналитические функции) и как быть уверенным, что оптимизатор не перепишет запрос и не начнёт выполнять запрос по другому, не в нужном мне порядке?
А никак. Поля выходного набора РАВНОЗНАЧНЫ. И управлять порядком их вычисления в принципе невозможно.

Может, сразу озвучите конкретную задачу? и лучше - в новой теме...
...
Рейтинг: 0 / 0
26.05.2015, 17:14:05
    #38969015
lamer yuga
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок вычисления переменных
GROUP BY выполняет группировку совмещенную с сортировкой
Если нужно нумеровать в другом порядке - сделайте это во внешнем запросе.
Должно получиться...
Код: sql
1.
2.
3.
4.
5.
6.
select @npp:=@npp+1 npp, g.* 
from (
  select ...
  group by ...
  )g
order by ...
...
Рейтинг: 0 / 0
26.05.2015, 17:18:04
    #38969021
mysql_noob
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок вычисления переменных
Akina,
задача банальна - взять предыдущее значения в разрезе группы, т.е. нужно с имитировать функцию Lag (t.dd) over (partition by t.gr order by t.dd) в других СУБД.
Подзапросом нереально, таблица тяжелая, 150 мил. записей, индексов нет - не дождаться ответа. Может скоро разобьём на партиции и добавим индекс, но сейчас надо так. Время за один проход сканирования таблицы, в принципе, приемлемое, но вложенные циклы с полным сканированием всё убивают.

Если нужно, то могу создать новую тему либо перейти, например, сюда
http://www.sql.ru/forum/1055940/vyborka-na-n-zapisey-vpered-i-nazad?hl=lag
...
Рейтинг: 0 / 0
26.05.2015, 17:20:13
    #38969025
mysql_noob
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок вычисления переменных
Akina,
задача банальна - взять предыдущее значения в разрезе группы, т.е. нужно с имитировать функцию Lag (t.dd) over (partition by t.gr order by t.dd) в других СУБД.
Подзапросом нереально, таблица тяжелая, 150 мил. записей, индексов нет - не дождаться ответа. Может скоро разобьём на партиции и добавим индекс, но сейчас надо так. Время за один проход сканирования таблицы, в принципе, приемлемое, но вложенные циклы с полным сканированием всё убивают.
...
Рейтинг: 0 / 0
26.05.2015, 17:21:37
    #38969030
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок вычисления переменных
mysql_noobмогу создать новую темуЖивите здесь, я вроде все успел сюда перетащить :)
...
Рейтинг: 0 / 0
26.05.2015, 17:23:25
    #38969031
mysql_noob
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок вычисления переменных
lamer yugaGROUP BY выполняет группировку совмещенную с сортировкой
Если нужно нумеровать в другом порядке - сделайте это во внешнем запросе.
Должно получиться...
Код: sql
1.
2.
3.
4.
5.
6.
select @npp:=@npp+1 npp, g.* 
from (
  select ...
  group by ...
  )g
order by ...


А есть гарантии, что оптимизатор не перепишет запрос и не изменит порядок вычислений?

miksoft,
Спасибо!
...
Рейтинг: 0 / 0
26.05.2015, 17:27:37
    #38969041
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок вычисления переменных
mysql_noon,

делать разными операторами Sql.
сначала первое действие, потом второе и т.д.
...
Рейтинг: 0 / 0
26.05.2015, 17:27:43
    #38969042
mysql_noob
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок вычисления переменных
lamer yugaGROUP BY выполняет группировку совмещенную с сортировкой
Если нужно нумеровать в другом порядке - сделайте это во внешнем запросе.
Должно получиться...
Код: sql
1.
2.
3.
4.
5.
6.
select @npp:=@npp+1 npp, g.* 
from (
  select ...
  group by ...
  )g
order by ...


Если честно, я так и не понял, как мне поможет group by, если мне на одном уровне select нужно одновременно читать и записывать значение переменной.
...
Рейтинг: 0 / 0
26.05.2015, 17:28:33
    #38969046
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок вычисления переменных
А, кстати, этот момент есть в нашем FAQ-е - 8379530
Не уверен, что там все правильно, но идея ясна - воспользоваться вызовом нейтральной функции. Тогда аргументы функции всегда буду вычисляться до присвоения.
...
Рейтинг: 0 / 0
26.05.2015, 17:31:02
    #38969050
lamer yuga
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок вычисления переменных
Akinamysql_noonКак тогда быть, если нужно сперва отобразить, потом изменить именно в определенном порядке (имитировать аналитические функции) и как быть уверенным, что оптимизатор не перепишет запрос и не начнёт выполнять запрос по другому, не в нужном мне порядке?
А никак. Поля выходного набора РАВНОЗНАЧНЫ. И управлять порядком их вычисления в принципе невозможно.
Вроде бы в доке я читал, что порядок вычислений значений переменных (в рамках одной записи) строго последовательный...
Да и иначе бы резко падала эффективность использования переменных в запросах

межстрочные вычисления переменных зависят от порядка поступления строк (т.е. от ORDER BY)

Во всяком случае, как правило так и происходит
...
Рейтинг: 0 / 0
26.05.2015, 17:32:40
    #38969053
lamer yuga
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок вычисления переменных
mysql_nooblamer yugaGROUP BY выполняет группировку совмещенную с сортировкой
Если нужно нумеровать в другом порядке - сделайте это во внешнем запросе.
Должно получиться...
Код: sql
1.
2.
3.
4.
5.
6.
select @npp:=@npp+1 npp, g.* 
from (
  select ...
  group by ...
  )g
order by ...


Если честно, я так и не понял, как мне поможет group by, если мне на одном уровне select нужно одновременно читать и записывать значение переменной.Это был ответ на пост от 2013 года :) Занесло как новый - ну я на него и ответил, не посмотрев на дату
...
Рейтинг: 0 / 0
26.05.2015, 17:44:23
    #38969066
lamer yuga
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок вычисления переменных
mysql_noonДобрый день. Читаю в доке следующий абзац
For other statements, such as SELECT, you might get the results you expect, but this is not guaranteed. In the following statement, you might think that MySQL will evaluate @a first and then do an assignment second:

Код: sql
1.
SELECT @a, @a:=@a+1, ...


However, the order of evaluation for expressions involving user variables is undefined.
Я понял так, что никто мне не гарантирует, что сперва покажется значение переменной @a, а затем этой к переменной прибавится ещё единица. Может быть наоборот, сперва прибавление единицы, а потом отображение значения переменной.

Написал тестовый запросик
http://sqlfiddle.com/#!2/9eecb7/162 v.5.5
Код: sql
1.
2.
select @a, @a:=@a+10, @a:=@a-100, @a:=@a+40, @a
from(select @a:=100)v;

результат - как и ожидалось, все по порядку@a @a:=@a+10 @a:=@a-100 @a:=@a+40 @a100 110 10 50 50
...
Рейтинг: 0 / 0
26.05.2015, 17:49:51
    #38969075
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок вычисления переменных
Мне пока не приходилось сталкиваться со случаем, когда бы вычисления в выходном наборе выполнялись НЕ в том порядке, в каком они перечислены в тексте запроса. И, в общем, я не вижу оснований к тому, что этот порядок бы не соблюдался - просто потому, что не существует алгоритмов оптимизации порядка вычисления выражений выходного набора (да и за каким хреном бы его делать? овчинка выделки не стОит).

К слову, у меня LAG() получился попроще твоего, кажется...
http://sqlfiddle.com/#!9/58240/7
...
Рейтинг: 0 / 0
26.05.2015, 17:55:59
    #38969087
mysql_noob
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок вычисления переменных
lamer yuga,
авторAs a general rule, other than in SET statements, you should never assign a value to a user variable and read the value within the same statement . For example, to increment a variable, this is okay:

Код: sql
1.
SET @a = @a + 1;


For other statements, such as SELECT, you might get the results you expect, but this is not guaranteed . In the following statement, you might think that MySQL will evaluate @a first and then do an assignment second:

SELECT @a, @a:=@a+1, ...;
However, the order of evaluation for expressions involving user variables is undefined.
http://dev.mysql.com/doc/refman/5.5/en/user-variables.html

lamer yugamysql_noonДобрый день. Читаю в доке следующий абзац
пропущено...

Я понял так, что никто мне не гарантирует, что сперва покажется значение переменной @a, а затем этой к переменной прибавится ещё единица. Может быть наоборот, сперва прибавление единицы, а потом отображение значения переменной.

Написал тестовый запросик
http://sqlfiddle.com/#!2/9eecb7/162 v.5.5
Код: sql
1.
2.
select @a, @a:=@a+10, @a:=@a-100, @a:=@a+40, @a
from(select @a:=100)v;

результат - как и ожидалось, все по порядку@a @a:=@a+10 @a:=@a-100 @a:=@a+40 @a100 110 10 50 50
Из доки как раз и следует, что может развращаться правильный результат, но он не детерменирован. Не хотелось бы, чтобы в определенных ситуациях отчет выдавал неверные вычисления, которые основаны на неверном результате этих переменных.

MasterZivmysql_noon,
делать разными операторами Sql.
сначала первое действие, потом второе и т.д.
Внимательно посмотрел и понял, что не получится. Зависимость одной переменной от другой внутри одного оператора select. Если бы не было разреза групп, то может быть и получилось. А так нужно отслеживать переход групп.
...
Рейтинг: 0 / 0
26.05.2015, 18:26:27
    #38969117
mysql_noob
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок вычисления переменных
AkinaК слову, у меня LAG() получился попроще твоего, кажется...
http://sqlfiddle.com/#!9/58240/7
Нуда, я перемудрил как-то )
...
Рейтинг: 0 / 0
28.05.2015, 05:05:28
    #38970295
javajdbc
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок вычисления переменных
miksoftА, кстати, этот момент есть в нашем FAQ-е - 8379530
Не уверен, что там все правильно, но идея ясна - воспользоваться вызовом нейтральной функции. Тогда аргументы функции всегда буду вычисляться до присвоения.

...угу, внутри нескольких функций порядок детерминирован.

7489069 ...в самом конце

Примечания:
@rownum:=1+least(0,@typex:=ta.type) гарантирует обновление @typex
после проверки "if(@typex=ta.type..."
...
Рейтинг: 0 / 0
28.05.2015, 05:20:43
    #38970296
javajdbc
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок вычисления переменных
mysql_noobAkina,
задача банальна - взять предыдущее значения в разрезе группы, т.е. нужно с имитировать функцию Lag (t.dd) over (partition by t.gr order by t.dd) в других СУБД.
Подзапросом нереально, таблица тяжелая, 150 мил. записей, индексов нет - не дождаться ответа. Может скоро разобьём на партиции и добавим индекс, но сейчас надо так. Время за один проход сканирования таблицы, в принципе, приемлемое, но вложенные циклы с полным сканированием всё убивают.


...если таких запросов много и надо быстро то
подходите к задаче более основательно:

1. Например добаить ЛАГ и ЛЕАД значении в каждую запись
одним проходом а потом быстро вычислять то что нужно.

3. вообше делите сложные запросы на части и выполняйте в независимых простых СКЛ-ах
Любые джоинты на больших таблицах вывалятся из памяти на диск
и все зависинет на минуты/часы и натрете мозоль диску.

2. посмотрите на процедурный курсор.
Возможно это поможет не вывалится на диск и закончится быстрее.
Кроме того в процедуре можно "партицировать"
курсор по блоку груп.

4. Добавить много-много памяти

5. Купить Оракле.

6. Почитайте про ОЛАП
...
Рейтинг: 0 / 0
28.05.2015, 11:17:55
    #38970488
mysql_noob
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок вычисления переменных
javajdbc, благодарю за советы. Попробую процедурное расширение в mysql.

Покупка oracle, конечно, кардинально бы всё решило, но увы.
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Порядок вычисления переменных / 19 сообщений из 19, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]