Это хорошо документированный шаблон? - PullRequest
3 голосов
/ 07 июля 2011

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

Контекст:

У вас есть метод / функция / процедура, которая делает несколько вызовов SELECT к базе данных, и вам нужночтобы оптимизировать его.

Допустим, поток вашего метода:

  getDBConnection()  
  execute("Select a,b from tableA");  
  bind a with varA 
  bind b with varB  
  ---SOME Business Logic-----  
  execute("Select c,d from tableB");  
  bind c with varC  
  bind d with varD   
  ---SOME more Business Logic-----  
  execute("Select e,f from tableC");  
  bind e with varE  
  bind f with varF  
  ---SOME more Business Logic-----  
  releaseConnection()

Решение: Используйте Union ALL, чтобы сделать один вызов в базу данных

 getDBConnection()
 execute("Select a,b,'sqlA' from tableA"+  
 " UNION ALL "+  
 " Select c,d,'sqlB' from tableB"+  
 " UNION ALL "+
 "Select e,f,'sqlC' from tableC");  
 bind a,b where records have "sqlA"   
 bind c,d where records have "sqlB"
 bind e,f where records have "sqlC"  
 releaseConnection()  
 --------Do all Business Logic here-----

Ответы [ 2 ]

6 голосов
/ 07 июля 2011

Использование union ограничивает «форму» ваших запросов. Все они в основном должны возвращать одинаковое количество и (совместимые) типы столбцов в одинаковом порядке.

Лучше было бы использовать несколько запросов в одной команде, а затем работать с несколькими наборами результатов:

execute("Select a,b from tableA;"+
  "Select c,d from tableB;"+
  "Select e,f from tableC");

Или, может быть, создать специальную хранимую процедуру, которая выполняет эти запросы.

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

1 голос
/ 08 июля 2011

Объединение всего вместе может замаскировать реальную проблему: знаете ли вы, откуда возникает задержка?

Если эти запросы вызываются много раз, вы, возможно, тратите много времени на этапе компиляции.Использование подготовленных операторов может помочь, если таблицы не претерпевают слишком значительных изменений в течение времени жизни вашего приложения:

conn = connect_to_db()
pstmt = conn.prepare('select ...')
...
pstmt.bind(parameters) // if necessary
pstmt.execute()

Если задержка не связана с компиляцией, это может быть выполнение - запросы, которые вы дали, являются простыми выборами, ночто-либо более сложное может потребовать проверки планов объяснения.

Если ваши базы данных и структура ваших таблиц позволяют это, некоторая реструктуризация может также помочь сократить объем запросов, которые необходимо выполнить: Можете ли вы объединить операторы selectс объединением вместо союза?Можете ли вы объединить таблицы с разбиением?

Это все общие идеи.Чтобы ответить на ваш актуальный вопрос, я не видел, чтобы этот подход использовался ранее, но я бы не позволил известности быть единственным решающим фактором.Как указывал предыдущий автор, вы можете пожертвовать возможностью повторного использования кода.Наконец, по мере роста количества таблиц этот подход будет не очень хорошо масштабироваться: вам все равно придется искать в строках кода «sqlA», «sqlB» и т. Д.

...