Где предложение не ограничивает записи, когда агрегат используется в select

Я прочитал, что он используется для оптимизации, но четко не определен ни в одном стандарте.

blockquote>

Фактически это является , четко определенным C. Цитирование N1570 draft раздела 6.7.1, пункт 6 (другие версии имеют одинаковую формулировку):

Объявление идентификатора для объекта с спецификатором класса хранения register предполагает, что доступ к объекту должен быть как можно быстрее. Степень, в которой такие предложения эффективны, определяется реализацией.

blockquote>

Унарный оператор & не может применяться к объекту, определенному с помощью register, а register может не быть используется в внешней декларации.

Существует несколько других (довольно неясных) правил, специфичных для register -qualified objects:

  • Определение объекта массива с помощью register имеет неопределенное поведение. Исправление: законно задавать объект массива с помощью register, но вы не можете ничего использовать с таким объектом (индексирование в массив требует ввода адреса его начального элемента).
  • _Alignas (новый в C11) не может быть применен к такому объекту.
  • Если имя параметра, переданное макросу va_start, [register -qualified, поведение не определено.

Могут быть несколько других; Загрузите черновик стандарта и выполните поиск «register», если вам интересно.

Как следует из названия, значение оригинала для register должно было требовать от объекта храниться в регистре CPU. Но с улучшением оптимизации компиляторов это стало менее полезным. Современные версии стандарта C не относятся к регистрам CPU, потому что они больше не нуждаются (должны) предполагать, что есть такая вещь (существуют архитектуры, которые не используют регистры). Общая мудрость заключается в том, что применение register к объявлению объекта с большей вероятностью ухудшает сгенерированный код, потому что это мешает распределению собственного регистра компилятора. Там может быть несколько случаев, когда это полезно (скажем, если вы действительно знаете, как часто переменная будет доступна, и ваши знания лучше, чем то, что может вычислить современный оптимизирующий компилятор).

основным ощутимым эффектом register является то, что он предотвращает любую попытку принять адрес объекта. Это не особенно полезно в качестве подсказки оптимизации, поскольку его можно применять только к локальным переменным, а оптимизационный компилятор может убедиться в том, что адрес такого объекта не принят.

0
задан HerrimanCoder 5 March 2019 в 03:53
поделиться

1 ответ

Это на самом деле ожидаемое поведение. Из руководства :

Без GROUP BY существует одна группа, и недетерминировано, какое значение [неагрегированный столбец] выбрать для группы.

Хотя это не очень четко указано, это означает, что вы всегда получаете одну группу (то есть одну строку), даже для пустой таблицы.

Также стоит подчеркнуть, что значения, которые MySQL выбирает для неагрегированных столбцов в ваших select, r.ID и r.ReservationDate, на самом деле являются недетерминированными и будут конкретно различаться в разных версиях MySQL (например, они обычно быть null для MySQL 8.0, в то время как они обычно будут содержать существующие значения для более ранних версий).

Решение аналогично тонкое - добавьте group by (чтобы цитируемое предложение больше не применяется):

...
where r.ConfirmationNumber = '123456'
and p.CCLast4 = 'xxx'
and r.ID = 54321
group by r.ID, r.ReservationDate

должно дать вам 0 строк.

0
ответ дан Solarflare 5 March 2019 в 03:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: