Можно всегда переписывать их для получения того же набора результатов. Однако иногда план выполнения может отличаться значительными способами (производительность) и иногда правильное соединение, позвольте нам, Вы выражаете запрос способом, который имеет больше смысла.
Позволяют мне проиллюстрировать различие в производительности. Программисты склонны думать с точки зрения sql оператора, происходящего внезапно. Однако полезно сохранить умственную модель, что сложные запросы происходят в серии шагов, где к таблицам обычно присоединяются в перечисленном порядке. Таким образом, у Вас может быть запрос как это:
SELECT * /* example: don't care what's returned */
FROM LargeTable L
LEFT JOIN MediumTable M ON M.L_ID=L.ID
LEFT JOIN SmallTable S ON S.M_ID=M.ID
WHERE ...
сервер будет обычно запускаться путем применения чего-либо, что он может от оператора Where до первой перечисленной таблицы (LargeTable, в этом случае), для сокращения то, что он должен загрузить в память. Тогда это присоединится к следующей таблице (MediumTable), и затем той после этого (SmallTable), и так далее.
то, Что мы хотим сделать, использовать стратегию, которая составляет ожидаемое влияние каждой объединяемой таблицы на результатах. В целом Вы хотите сохранить набор результатов как можно меньше максимально долго. Примените тот принцип к запросу в качестве примера выше, и мы видим, что это, очевидно, намного медленнее, чем это должно быть. Это запускается с больших наборов (таблицы) и работы вниз. Мы хотим начать с меньших наборов и обработать. Это означает использовать SmallTable сначала и способ сделать, который является через ПРАВИЛЬНОЕ СОЕДИНЕНИЕ.
Другой ключ здесь - то, что сервер обычно не может знать, какие строки от SmallTable будут необходимы, пока соединение не завершается. Поэтому только имеет значение, если SmallTable настолько меньше, чем LargeTable, что загрузка всего SmallTable в память является более дешевой, чем, с чего Вы запустили бы от LargeTable (который, будучи большой таблицей, вероятно, хорошо индексируется и вероятно фильтрует на поле или три в где пункт).
важно также указать, что в подавляющем большинстве случаев оптимизатор посмотрит на это и обработает вещи самым эффективным возможным способом, и большую часть времени оптимизатор собирается сделать лучшее задание в этом, чем Вы могли.
, Но оптимизатор не прекрасно. Иногда необходимо способствовать ему: особенно, если один или несколько Ваших "таблиц" является представлением (возможно, в связанный сервер!) или вложенный избранный оператор, например. Вложенный подзапрос является также хорошим случаем того, где Вы могли бы хотеть использовать правильное соединение по выразительным причинам: это позволяет Вам переместить вложенную часть запроса вокруг, таким образом, можно сгруппировать вещи лучше.
Я уже видел это раньше. Я очистил проект, сбросил симулятор и перезапустил XCode - похоже, это исправило. Я не знаю, почему произошла ошибка.
Это означает, что в Xcode отсутствует необходимый фреймворк.
Попробуйте добавить фреймворк, UIKit.framework , затем выполните сборку заново.
Попробуйте удалить проект «Build» каталог и снова создавать, это решило проблему для меня.
Я попробовал повторно добавить каркасы, упомянутые в каждом сообщении об ошибке, но в конечном итоге обходится круглые круги с помощью Xcode, жалующейся на отсутствие пропущенных структур, которые я только что повторно добавил.
У меня такая же проблема. Я испробовал все приведенные выше предложения, они не решат мою проблему. Наконец-то я нашел решение:
На самом деле я предлагаю вам сбросить симулятор и также очистить все цели. У меня это работает, вы можете найти оригинал разместите здесь: http://forums.pragprog.com/forums/83/topics/1095
После обновления до XCode 3.2.3 сегодня мое приложение для iPad отображало следующее сообщение в симуляторе
dyld: Библиотека не загружена: /System/Library/Frameworks/UIKit.framework/UIKit
Я могу подтвердить, что удаление папки сборки (а не только очистка целевого объекта) решит проблему. Спасибо, Эдди