ColdFusion: Запрос VS Структуры

В настоящее время у меня есть запрос внутри цикла, как показано ниже.

<cfloop query="Superquery">
    <cfquery datasource="mysource" name="getData">
        SELECT col1, Col2
        FROM myData
        where col1 = #Superquery.IDCol#
    </cfquery>
    <!--- Some Processing --->
</cfloop>

Запрос не возвращает много данных. В некоторых случаях он возвращает менее 100 строк, а в некоторых может возвращать около 5000 строк. Но так как он находится внутри цикла и количество итераций может превышать 100, это заставляет меня задуматься о лучшем подходе к оптимизации.

Подход 1. Использование запроса запросов

<cfquery datasource="mysource" name="getAllData">
        SELECT col1, Col2
        FROM myData
</cfquery>
<cfloop query="Superquery">
    <cfquery dbtype="query" name="getData">
        SELECT col1, Col2
        FROM getAllData
        where col1 = #Superquery.IDCol#
    </cfquery>
    <!--- Some Processing --->
</cfloop>

Подход 2. Используйте структуры

Вне цикла у меня есть запрос getAllData в соответствии с подходом 1 и создание структуры с ключом как «col1» и значением как «col2». Внутри цикла я использую структуру, созданную вне цикла, для выполнения необходимой обработки.

Я не уверен, имеет ли это значение в производительности между двумя подходами. Однако подход 1 легко реализовать. :) Просто думал получить некоторые предложения. Любые другие эффективные подходы приветствуются.

Спасибо!!


person Crash OR    schedule 06.05.2015    source источник
comment
Подход номер 3, вероятно, будет наиболее эффективным. Это тот, где вы придумываете способ вообще избежать петли. Детали зависят от ряда вещей, начиная с суперзапроса и получения всех данных, использующих один и тот же источник данных.   -  person Dan Bracuk    schedule 06.05.2015
comment
Вы предлагаете мне включить таблицу БД, поскольку она использует тот же источник данных? Что касается циклической части, я на самом деле устанавливаю некоторые переменные массива в цикле и использую их для дальнейшей обработки позже. Я не могу придумать, как в этом случае избежать цикла. От каких деталей это зависит?   -  person Crash OR    schedule 06.05.2015
comment
По мнению Дэна, вы захотите JOIN или что-то в этом роде. Подход 1 просто требует проблем с производительностью и использованием памяти. (Кроме того, если вы настаиваете на одном, используйте <cfqueryparam>   -  person James A Mohler    schedule 06.05.2015
comment
Детали зависят от того, что вы пытаетесь сделать. Однако, если все таблицы находятся в одной базе данных, зачастую более эффективно получить все необходимые данные с помощью одного запроса. Однако часто бывает не так, как всегда. Другой альтернативой запросу внутри цикла является запуск Q of Q с использованием ValueList и циклическим просмотром этих результатов.   -  person Dan Bracuk    schedule 06.05.2015
comment
Вариант 3, как уже отмечали другие, должен заключаться в использовании JOINS   -  person Scott Stroz    schedule 06.05.2015
comment
Я бы согласился с Дэном и Скоттом, однако Q из Q часто достаточно хорош. Протестируйте и посмотрите. вы можете получить выгоду в зависимости от сети и / или от того, насколько загружен ваш сервер БД. Если да, отлично, если нет, попробуйте провести рефакторинг с соединением.   -  person Mark A Kruger    schedule 06.05.2015
comment
Спасибо за предложение, ребята. Я реализую то же самое и дам вам знать в случае повышения производительности.   -  person Crash OR    schedule 06.05.2015
comment
Привет ребята! После внедрения исправления вот мое наблюдение, сделанное в течение недели: всякий раз, когда мы включаем запрос в цикл, он выдает оператор Create для каждого запроса, который должен выполняться для каждой итерации. Итак, если цикл выполняется 1000 раз и для выполнения запроса нет условной логики, в базу данных выдается 1000 операторов Create. Это увеличивает время ввода-вывода. Как было предложено, я реализовал соединения, тем самым устранив необходимость включения запроса в цикл и тем самым сократив время ввода-вывода. Если количество итераций очень велико, это время ввода-вывода может быть очень значительным.   -  person Crash OR    schedule 12.05.2015


Ответы (2)


Запрос запросов на самом деле довольно медленный по сравнению с SQL-запросом, поскольку он не имеет концепции индексов или планов выполнения, поэтому вам нужно быть осторожным, прежде чем идти по этому пути, поскольку вы вполне можете получить более медленный и интенсивный процесс. Механизмы баз данных оптимизированы для быстрого выполнения подобных операций.

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

В идеале вы хотите иметь возможность выполнять соединение между myData и таблицами, которые создают ваш Superquery запрос. Затем вы можете повторить этот запрос и обработать его по мере необходимости, не обращаясь снова к базе данных.

person John Whish    schedule 06.05.2015

Кажется, что создание структуры все усложняет.
Запрос сам по себе является структурой массивов.
Что бы вы ни хотели сделать, создав другую структуру, вы можете сделать это и с помощью запроса.
Похоже, что структура по сравнению с запросом запроса не имеет дополнительных преимуществ.
Если вы действительно хотите оптимизировать вещи, лучше попробуйте изменить свой запрос.
Например, как говорили другие, вы можете попробовать использовать какой-то JOIN в своем запросе, чтобы избавиться от цикла.

person Pankaj    schedule 06.05.2015