Имя: Пароль:
1C
1С v8
Первые 1
0 Мандалай
 
30.07.19
09:34
Добрый день.
Предположим есть справочник Х. В нем n элементов.
Есть запрос к справочнику:
"Выбрать Первые 1 ссылка из Справочник.Х"
Внимание вопрос:
Всегда ли в результате выполнения запроса будет возвращен один и тот же элемент?
1 Cyberhawk
 
30.07.19
09:35
Не гарантируется
2 ДенисЧ
 
30.07.19
09:35
Если сортировка не указана, то не обязательно.
3 Натуральный Йог
 
30.07.19
09:36
Безумие - это точное повторение одного и того же действия, раз за разом, в надежде на изменение.
4 Натуральный Йог
 
30.07.19
09:37
(2) Если не указана, то подрубается рандомная сортировка или всё таки есть какая-то сортировка по-умолчанию?
5 Волшебник
 
30.07.19
09:37
для стабильности результата нужна сортировка
по умолчанию будет выбран первый попавшийся, т.е. любой
6 ДенисЧ
 
30.07.19
09:38
(4) Нет. Никакого умолчания нет. Есть надежда (но это глупое чувство), что будет в порядке кластерного индекса. На надеяться на неё...
7 Натуральный Йог
 
30.07.19
09:39
(6) (5) Есть же алгоритм вычисления этого "любого", вы же не верите в реальный компьютерный рандом или свободу воли ИИ?
8 Мандалай
 
30.07.19
09:40
Коллеги, аргументируйте свое мнение.
9 Fish
 
30.07.19
09:42
(8) 1С об этом говорит. Ссылку сейчас не найду, емнип, на ИТС можно почитать.
10 Мандалай
 
30.07.19
09:45
Мы говорим о клиент-серверной архитектуре.
В данном случае имеет смысл прислушаться не только к мнению 1С, но и к мнению разработчика СУБД.
В моем случае SQL. Что MS говорит по этому поводу?
11 Волшебник
 
30.07.19
09:45
(7) это уже зависит от SQL, а он может оценить наличие записей в кэше и выбрать ближайшую из кеша
12 Натуральный Йог
 
30.07.19
09:46
(11) А если файловая?
13 Волшебник
 
30.07.19
09:46
(10) MS говорит так: если сортировка не указана в запросе, то порядок записей не гарантируется

(12) На файловых нормальные люди не работают.
14 ДенисЧ
 
30.07.19
09:50
(8) Это не мнение, это знание, подчерпнутое из докмеентации
15 ДенисЧ
 
30.07.19
09:50
(10) МС говоорит то же самое. Порядок не определен
16 Натуральный Йог
 
30.07.19
09:54
(13) Нормальные люди не выбирают первый попавшийся элемент справочника
17 Cyberhawk
 
30.07.19
09:57
(16) Конечно же выбирают, когда подразумевается что он один
18 2S
 
30.07.19
09:58
(16) бывает, для определения типа, например
19 Натуральный Йог
 
30.07.19
10:00
(17) Тогда результат всегда будет одинаковый
20 НЕА123
 
30.07.19
10:00
(18)
неа. для определения типа - ПЕРВЫЕ 0
21 Cyberhawk
 
30.07.19
10:01
(19) Всегда может появиться новый элемент справочника. Например, изначально подразумевается, что договор у контрагента всегда один и поэтому везде в алгоритмах закладывается "выбрать первый попавшийся".
22 НЕА123
 
30.07.19
10:02
+(20)
для определения существования хотя бы одной записи - ПЕРВЫЕ 1
23 Василий Алибабаевич
 
30.07.19
10:02
(16) Для проверки - есть ли там вообще хоть что-то. Зачем выбирать все? Достаточно любого первого.
24 palsergeich
 
30.07.19
10:02
История из жизни.
Давным давно я написал запрос к регистру данныеПроизводственныхКалендарей. Для получения какой то даты в рабочих днях.
Он больше года работал как часы.
Потом базу перезалил из ДТ и результат сломался. Оказалось порядок возвращаемых строк стал другой.
Была добавлена сортировка в текст запроса явно и снова стало все хорошо.
25 Успехов
 
30.07.19
10:03
(0) Практика показывает, что не всегда.
26 VladZ
 
30.07.19
10:09
(0) Нет гарантий, что возвращаться будет одно и то же значение.
27 unregistered
 
30.07.19
10:28
(21) >> изначально подразумевается, что договор у контрагента всегда один и поэтому везде в алгоритмах закладывается "выбрать первый попавшийся".

Это косяк архитектора ("изначально подразумевается") и разработчика, который заложил это в алгоритмах. Иногда это называют логической бомбой. Потому что рванёт в неизвестном месте и в неизвестное время.
Всегда, когда встречается подобная задача, как бы заказчики или методисты (авторы ТЗ) не клялись, что элемент будет только один, никогда не ведусь у них на поводу и обрабатываю ситуации исходя из наличия более одного элемента.
28 unregistered
 
30.07.19
10:30
(18) >> для определения типа, например.

Для определения типа не важно - какое именно значение получено (какой конкретно элемент попал в выборку). Автору ветки критично получить конкретный элемент.
29 Cyberhawk
 
30.07.19
10:31
(27) Не косяк, а именно так и задумано
30 unregistered
 
30.07.19
10:32
(22) >> для определения существования хотя бы одной записи.

Аналогично задачи определения типа. Тут не важно какой конкретно элемент мы получим и сколько их - важно, что они там вообще есть.
31 Жан Пердежон
 
30.07.19
10:34
(7)(8) если сортировка не указана явно, то порядок никто не гарантирует.
этого уже должно быть достаточно, чтобы не задавать такие глупые вопросы.
32 unregistered
 
30.07.19
10:34
(29) Плохо значит задумано. Если договор всегда один, то нафига справочник?
А если уж запилили справочник, то разработчик должен был подумать о том, что ни что не вечно под луной и там, где есть один договор, рано или поздно с вероятностью 99.9% появится и второй, и третий, и т.д.
33 unbred
 
30.07.19
10:35
(21) >изначально подразумевается, что договор у контрагента всегда один
Кем подразумевается? это в техДокументации? что за ересь?
34 Cyberhawk
 
30.07.19
10:37
(32) "разработчик должен был подумать о том" // От таких обобщающих дум проекты не делаются
35 Cyberhawk
 
30.07.19
10:37
(33) Бизнесом / постановщиком / кем-нибудь еще в цепи до разработчика
36 unregistered
 
30.07.19
10:38
(33) А почему бы и нет? Сплошь и рядом постановщики формулируют свои хотелки в такой форме. Мамой клянутся, что *ля будут, но всегда только один договор.
37 palsergeich
 
30.07.19
10:40
(36) Когда мамой клянутся - 100% через неделю будет как минимум одно исключение из правил. Это наблюдение у меня работает в 100% случаев
38 palsergeich
 
30.07.19
10:40
(37) чем больше уверяют в невозможности события, тем раньше оно произойдет
39 unregistered
 
30.07.19
10:41
(34) Не понял твоей мысли.

(35) Бизнес вообще в технические нюансы написания запросов не вникает.
Постановщик - да. В идеале именно он должен думать о подобных вещах. В реальной жизни это, как правило, всё таки разработчик. Потому что именно он решает как именно реализовать алгоритм описанный в ТЗ. Вот ему и приходится писать запрос правильно - с учетом возможного наличия более одного элемента в выборке.
40 Фрэнки
 
30.07.19
10:43
Ответ просили дать на простой вопрос :

// Всегда ли в результате выполнения запроса будет возвращен один и тот же элемент?

Ответ - не всегда. В базе возможны действия, которые изменяют результаты запросов.
И не важно, сколько запрашивается записей - одна или несколько - результаты запросов изменяются если с базой происходят какие-то изменения.
41 Cyberhawk
 
30.07.19
10:45
(39) Обобщать требования, думать наперед и делать непрошенные проверки - корень многих бед. Например, отодвигание даты выката очередного релиза.
42 Cyberhawk
 
30.07.19
10:46
(39) Ну вот бизнес и постановщик решили, что подумают об этом потом - если возникнет - а пока брать первый попавшийся
43 unregistered
 
30.07.19
10:53
(41) Ну естественно, что всё должно быть в разумных пределах (думать наперед и делать непрошенные проверки).
Но в данном конкретном примере, ИМХО, разработчик просто обязан такие вещи предусматривать.
44 unregistered
 
30.07.19
10:57
(42) Да пусть думают что угодно. Текст запроса пишет разработчик. Запрос должен гарантированно вернуть один единственный элемент и не просто один, а всегда один и тот же. Вне зависимости от изменения каких-либо условий и обстоятельств. Появление в справочнике более одного элемента договора - это естественное и нормальное явление (в отличие от, например, регистра сведений с единственным ключом), которое разработчик должен ожидать и предусмотреть.
45 fisher
 
30.07.19
11:09
(30) В сиквеле страничная организация хранения данных и поэтому никакого неявного порядка при отсутствии явной сортировки не гарантируется.
Ты можешь получать повторяемый результат в "наколенных" тестах, но при изменении внутреннего состояния системы (перезапуске сиквела, переиндексации, обновлении статистики, сброса кэшей) он легко может измениться.
46 H A D G E H O G s
 
30.07.19
11:14
(0) Теоретически - нет, практически - да.
47 Волшебник
 
30.07.19
11:14
(46) и практически нет. Это приходит с опытом.
48 fisher
 
30.07.19
11:23
Тьфу, (45) было к (0)
49 fisher
 
30.07.19
11:29
Хотя... При наличии кластерного индекса в mssql... Возможно, что результат будет повторяемый всегда, тут не уверен. Но MS это в любом случае это официально не гарантирует. А следовательно даже если неявная сортировка в каких-то случаях и существует, то полагаться на недокументированные фичи как минимум непрофессионально.
50 Cyberhawk
 
30.07.19
12:00
(44) "Запрос должен гарантированно вернуть один единственный элемент и не просто один, а всегда один и тот же" // В сценарии появления новых элементов в справочнике задача в общем случае не решается
51 Cyberhawk
 
30.07.19
12:03
(49) Если выполнение запроса использует кластерный индекс, то конечно порядок будет всегда один и тот же. Но и тут только до первого перестроения индекса (пришла какая-нибудь ссылка по обмену с левым непоследовательным УИДом и привет).
Но он не всегда может использоваться.
52 Salimbek
 
30.07.19
12:05
(44) Ну допустим тебе поставили задачу: Создать новый регистр накопления, сумму для него взять из Документов вида ХХХ, как-то там обработать и записать в этот новый Регистр с привязкой к Договору. При этом мамой клянутся, что у каждого Контрагента лишь один договор и всю сумму надо сажать именно на него. Делов там на полчаса-час.
И тут разработчик такой - нет, я вам не верю, надо учесть, что договоров может быть много и надо кроме простейшей обработки ранее написать еще и блок распределения этих сумм по Договорам, причем с вариантами: 1) делить суммы между договорами пропорционально; 2) делать аналитический выбор, при помощи нейросети, на какой договор сажать и 3) с интерфейсом для Ответственных, чтобы суммы люди сами раскидывали.
Так что-ли?
53 Волшебник
 
30.07.19
12:08
(51) Кластерный индекс по полю ускоряет сортировку по этому полю, если она указана в запросе. Если в запросе нет указания на сортировку, то физический порядок записей в таблице (т.е. кластерный индекс) может игнорироваться. Там же сложные деревья. Зачем СУБД читать эти деревья, если сказано "первый попавшийся"? Значит у неё появляется простор для творчества, вот она и творит каждый раз разный результат, который может _случайно_ совпадать с предыдущим.
54 palsergeich
 
30.07.19
12:09
(52) именно так и происходит.
Потому что есть какой нибудь особенный например Ашан, о котором все забыли.
55 rsv
 
30.07.19
12:11
(0) что по этому поводу пишет  msdn ? ,первые он же top это скуль
56 palsergeich
 
30.07.19
12:12
(54) 2 варианта развития событий:
требую время на анализ. Чем больше торопят - значит тем большая жопа ждет.
- предупреждаю об опасности, а потом нещадно троллю.
Подумать потом сделать условно 40 часов.
Сделать, забить НСИ, потом переделать -  400.
Ещё ни разу быстрое решение не оказалось действительно быстрым
57 H A D G E H O G s
 
30.07.19
12:21
(53) СУБД прочитает дерево индекса, а не таблицу данных, если в дереве есть необходимые поля.
58 Волшебник
 
30.07.19
12:22
(57) в случае кластерного индекса, о котором тут идёт речь, он хранится вместе с данными
59 Cyberhawk
 
30.07.19
12:27
(56) Есть еще два варианта развития:
- предупреждаю, а факап не наступил, троллить некого )
- беру время на анализ, делаю все по фен-шую, а оно не пригождается ни разу
60 palsergeich
 
30.07.19
12:29
(59) Счастливый человек.
61 palsergeich
 
30.07.19
12:31
(60) У меня все наоборот. Переделка функционала занимает раз в 10 больше времени, чем его разработка.
И это постоянно, я уже заипалсо всем что то доказывать. "Сделаем запустим, остальное как нибудь"
И вот уже сколько мест работы поменял - одно и то же
62 fisher
 
30.07.19
12:33
(58) В случае кластерного индекса он сам и есть данные. Поэтому я вполне допускаю, что проще было реализовать взять первую запись в рамках стандартного сканирования по кластерному индексу, чем как-либо иначе.
63 dk
 
30.07.19
12:37
может взять любую страницу которая не вымылась из кэша - не факт что это будет первая страница
теорий слишком много
64 Cyberhawk
 
30.07.19
12:40
(61) То что ты описываешь конечно встречается, и даже достаточно часто (что переделка затратнее, чем сразу было бы подумать).
Приходится либо почти откровенно динамить прокладку-постановщика (который тяму не напряг), либо брать инициативу и делать часть его работы, улучшая постановку. Вот второе абсолютно везде встречается, что лично для меня печально (не всегда с качественными прокладками доводится работать).
65 fisher
 
30.07.19
12:44
(62) + Но тогда это будет работать только для кластерного индекса, отражающего порядок добавления записей в таблицу. И как раз для таблиц ссылочных типов 1С оно так и есть. 1С специально в гуиде временную составляющую ставит в начало, чтобы минимизировать вставки в середину индекса.
Тогда теоретически можно сгенерить такой гуид для элемента справочника через УстановитьСсылкуНового, который "сломает" выдачу "одного и того же" в "ПЕРВЫЕ 1".
66 Cyberhawk
 
30.07.19
12:44
(65) Что-то ты повторяешь (51) :)
67 fisher
 
30.07.19
12:46
(66) Действительно :)
68 rsv
 
30.07.19
12:46
Вот что пишет msdn

Если вы используете TOP с предложением ORDER BY, в результирующий набор включаются только первые N строк отсортированного результата. В противном случае TOP возвращает N строк в неопределенном порядке.
69 rsv
 
30.07.19
12:48
В инструкции SELECT всегда указывайте ORDER BY вместе с предложением TOP. Дело в том, что это единственный предсказуемый способ отбора строк предложением TOP.
70 H A D G E H O G s
 
30.07.19
12:49
Забудьте про кластерный индекс, ибо в справочнике всегда будет некластерный индекс, в котором есть ссылка - например, по наименованию или по коду и SQL будет использовать его. И как только сменяться коды справочника или наименования - будет выбран другой первый, поэтому я беру свои слова (46) обратно, в которых я посмотрел в сторону кластерного индекса.
71 fisher
 
30.07.19
12:51
(70) "и SQL будет использовать его" - почему?
72 H A D G E H O G s
 
30.07.19
12:53
(71) Ну дык читать некластерный индекс проще, чем кластерный. Там полей меньше.
73 Вафель
 
30.07.19
12:55
(72) абсолютно одинаково
74 Cyberhawk
 
30.07.19
12:56
Ну вот, началось
75 fisher
 
30.07.19
12:57
(72) Для ПЕРВЫЕ 1? Крутая оптимизация.
76 Cyberhawk
 
30.07.19
12:58
(75) А какая разница для "первые 1" читать кластерный или некластерный?
77 fisher
 
30.07.19
12:59
Да и даже для "ПЕРВЫЕ 1000 Ссылка, Наименование" я сильно сомневаюсь, что оптимизатор будет специально искать вторичный покрывающий индекс при отсутствии явной сортировки.
78 fisher
 
30.07.19
13:01
(77) + Вместо того, чтобы тупо взять первые 1000 по кластерному индексу. Там оптимизировать уже нечего.
79 H A D G E H O G s
 
30.07.19
13:03
(73) SQL-ю пофиг на строки. Ему важен размер строки.
80 H A D G E H O G s
 
30.07.19
13:04
Я просто оставлю это здесь
http://prntscr.com/olx55u
81 H A D G E H O G s
 
30.07.19
13:04
Тоже был удивлен и тоже задался вопросом, почему так.

Нашел даже в msdn объяснение, выкладывал на мисте.
82 Вафель
 
30.07.19
13:05
(79) думаешь он всю строку зачитывает, даже если всего 1 поле?
83 H A D G E H O G s
 
30.07.19
13:05
84 fisher
 
30.07.19
13:05
(80) Надо же. Век живи - дураком помрешь.
85 fisher
 
30.07.19
13:08
(83) Спасибо за инфу. До этого момента не натыкался.
86 H A D G E H O G s
 
30.07.19
13:10
Насколько sql не хочет юзать кластерный индекс
http://prntscr.com/olx8oo
87 rsv
 
30.07.19
13:15
(80) можно явно хинт и посмотреть план
88 palsergeich
 
30.07.19
13:16
(81) я тоже нашел и выкладывал.
Там очень четко сказано, что количество полей в индексе - один из параметров принятия решения)
89 H A D G E H O G s
 
30.07.19
13:16
(87) Зачем?
90 rsv
 
30.07.19
13:16
но это уже не чистый эксперимент а подсказка оптимизатору скуль и это зачем то поидумал
91 rsv
 
30.07.19
13:22
(89) так хинты вроде и призваны менять поведение явно
92 НЕА123
 
30.07.19
13:25
(30)
>Аналогично задачи определения типа. Тут не важно какой конкретно элемент мы получим и сколько их - важно, что они там вообще есть.

тип есть, а записей может и не быть.
поэтому ПЕРВЫЕ 0.
93 H A D G E H O G s
 
30.07.19
13:29