2009-05-20 4 views
1

Недавно я столкнулся с проблемой, когда запрос вызывал полное сканирование таблицы, и у него появилось другое определение, которое, как я думал, было VARCHAR, а не INT. При запросе с «string_column   =   17« запрос запустился, он просто не мог использовать индекс. Это действительно бросило меня в петлю.Преобразование типа MySQL: почему float самый низкий общий тип знаменателя?

Так что я отправился на поиски и нашел то, что случилось, поведение я видел это согласуется с тем, что MySQL's documentation говорит:

Во всех других случаях аргументы сравниваются как с плавающей точкой (вещественных) чисел.

Так что мой вопрос ... почему плавание?

Я мог видеть попытку преобразования чисел в строки (хотя точки на странице MySQL, приведенные выше, являются вескими причинами). Я также мог понять, что я выбрал какую-то ошибку или создал предупреждение (мои предпочтения). Вместо этого он с радостью работает.

Так зачем же конвертировать все в поплавок? Это из стандарта SQL или по другой причине? Может ли кто-нибудь пролить свет на этот выбор для меня?

+0

Возможно, аргументы: any_column = 17 пытается сравнить any_column с числом, поэтому давайте посмотрим, будем ли мы качать any_column на число, а затем сравниваем. – pts

+0

Да, эта вещь фиксирует столбец. На самом деле это была ошибка с моей стороны, в первую очередь, поскольку у меня было неправильное определение столбца в моей голове. Этот вопрос заключается в том, чтобы выяснить, есть ли какая-то очевидная причина, что это может быть сделано, о чем я не думаю. Я бы скорее получил ошибку, которая заставила его тихо попытаться. – MBCook

ответ

2

Я чувствую вашу боль. У нас есть колонка в нашей БД, которая содержит то, что хорошо известно в компании как «номер заказа». Но это не всегда число, в определенных обстоятельствах у него могут быть и другие персонажи, поэтому мы держим его в варчаре. С SQL Server 2000 это означает, что выбор «order_number = 123456» является плохим. SQL Server эффективно переписывает предикат "CAST(order_number, INT) = 123456" который имеет два нежелательных эффектов:

  1. индекс находится на order_number как VARCHAR, поэтому он запускает полное сканирование
  2. те нецифровых порядковые номера в конечном итоге привести к ошибке преобразования в быть брошенным пользователю, с довольно бесполезным сообщением.

В любом случае хорошо, что у нас есть эти нечисловые «числа», поскольку по крайней мере плохо написанные запросы, которые передают параметр как число, попадают в ловушку, а не просто всасывают ресурсы.

Я не думаю, что есть стандарт. Я, кажется, помню, что PostgreSQL 8.3 сбросил некоторые из заданий по умолчанию между числами и текстовыми типами, чтобы такая ситуация вызывала ошибку при планировании запроса.

Предположительно, «поплавок» считается самым широким числовым типом и, следовательно, тем, к которому можно бесшумно продвигать все числа?

О, и подобные проблемы (но без ошибок преобразования), когда у вас есть столбцы varchar и приложение Java, которое передает все строковые литералы как nvarchar ... внезапно ваши индексы varchar больше не используются, удачи в поиске вхождений это происходит. Конечно, вы можете сказать, что приложение Java отправляет строки как varchar, но теперь мы застряли только с использованием символов в windows-1252, потому что это то, что было создано БД 5-6 лет назад, когда это было просто «стоп-решение», , ах-ха.

0

Хорошо, это легко понять: float способен удерживать наибольший диапазон чисел.

Если, например, базовый тип данных datetime, он может быть просто преобразован в число с плавающей точкой, которое имеет одно и то же внутреннее значение.

Если тип данных является string, его легко разобрать на поплавок, ухудшая производительность, не выдерживая.

Таким образом, тип данных с плавающей точкой лучше отложить.

Смежные вопросы