2011-11-09 3 views
3

В принципе, у меня есть несколько запросов, как это:Mysql создать SQL подзапрос ALIAS

SELECT a, b, c FROM (LONG QUERY) X WHERE ... 

Дело в том, я использую этот длинную очередь очень часто. Я ищу, чтобы дать этот подзапрос псевдоним, который будет в первую очередь:

  1. Сокращенно & упрощать запросы (также уменьшить количество ошибок и дублирования кода)
  2. Возможно оптимизировать производительность. (Я считаю, что это делается по умолчанию, кэширование запросов тузды)

До сих пор, я делал это таким образом, чтобы сохранить:

variable = LONG QUERY; 
Query("SELECT a, b, c FROM ("+variable+") X WHERE ..."); 

Который не плохо. Я ищу способ сделать это с помощью mysql внутри.

Возможно ли создать простой, доступный только для чтения вид, который будет генерировать NO накладные расходы, чтобы я мог делать везде? Я считаю, что это более удобный способ сделать это.

SELECT a, b, c FROM myTable WHERE ... 
+1

Каждая вещь будет иметь накладные расходы в некоторой степени. IME, SQL не поддается повторному использованию кода, как Java/.NET/etc. SQL кэширует весь запрос, а не его части (включая чувствительность к регистру). –

+0

Я считаю, что слышал, что mySQL также кэширует подзапросы. Однако я не знаю, насколько это верно. –

+1

MySQL, а также SQL вообще (Oracle, SQL Server, может быть, PostgreSQL тоже) не кэширует части запроса. –

ответ

5

Обычно они называются виды. Например:

CREATE VIEW vMyLongQuery 
AS 
    SELECT a, b, c FROM (LONG QUERY) X WHERE ... 

, который затем может быть ссылка как это:

SELECT a, b, c FROM vMyLongQuery 

Смотрите http://dev.mysql.com/doc/refman/5.0/en/create-view.html для получения дополнительной информации о синтаксисе.

Что касается производительности, производительность в лучших случаях будет примерно такой же, как и то, что вы сейчас делаете, и в худшем случае это убьет ваше приложение. Это зависит от того, что вы делаете с представлениями и как MySQL их обрабатывает.

MySQL реализует представления двумя способами: merge и temptable. Опция merge - это точно то, что вы делаете сейчас, ваше представление объединено в ваш запрос как подзапрос. С соблазнительным он будет фактически спутать все данные в соблазнительные, а затем select/join к этому соблазнительному. Вы также теряете преимущества индекса, когда данные присоединяются к соблазнительной.

Как и в случае с голосом, план запроса merge не поддерживает ни одно из следующих действий на вашем экране.

  • Агрегатные функции (SUM(), MIN(), MAX(), COUNT(), и так далее)
  • DISTINCT
  • ГРУППА ПО
  • HAVING
  • LIMIT
  • UNION или UNION ALL
  • Подзапрос в избранном списке
  • Ссылка на литералы без базовой таблицы

Так что, если ваш подзапрос использует их, вы, вероятно, повредите производительность.

Кроме того, внимательно рассмотрите совет OMG Ponies, вид не совпадает с базовым классом. Представления имеют свое место в БД, но их легко можно использовать неправильно. Когда инженер приходит в базу данных с фона OO, представления кажутся удобным способом продвижения наследования и повторного использования кода. Часто люди в конечном итоге оказываются в положении, когда у них есть вложенные представления, соединенные с вложенными представлениями вложенных представлений. SQL обрабатывает вложенные представления, по существу принимая определение каждого отдельного представления и расширяя его до зверя запроса, который заставит вас кричать администраторам.

Кроме того, вы следовали отличной практике в своем примере, и я призываю вас продолжить это. Вы указали все свои столбцы отдельно, никогда не используйте SELECT * для указания результатов вашего представления. Это, в конечном счете, разрушит ваш день.

+0

Ваш ответ бог. Спасибо за разъяснение! Но у меня проблема, SQL дает мне ошибку: 'SELECT SELECT содержит подзапрос в предложении FROM'. Я боюсь, что мой запрос не может быть переписан таким образом. –

+1

Попробуйте написать представление как только подзапрос, не пытайтесь инкапсулировать весь запрос. Подумайте о размещении своего кода, и мы постараемся помочь. –

+0

Это действительно базовое: 'CREATE VIEW updatesLast AS SELECT artistSiteID, timeID, number, rank FROM updates NATURAL JOIN (SELECT artistSiteID, MAX (timeID) как timeID FROM updates GROUP BY artistSiteID) Y' –