Эффективность SQL: ГДЕ В Подзапросе по сравнению с Соединением затем ГРУППА

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

Предположим, у нас есть класс с именем StreamArrayReader с некоторыми закрытыми полями:

private:
    istream * in;
      // More private fields

И мы хотим определить два конструктора:

public:
    StreamArrayReader(istream * in_stream);
    StreamArrayReader(char * filepath);
    // More constructors...

Когда второй просто использует первый (и, конечно, мы не хотим дублировать реализацию первого). В идеале, хотелось бы сделать что-то вроде:

StreamArrayReader::StreamArrayReader(istream * in_stream){
    // Implementation
}

StreamArrayReader::StreamArrayReader(char * filepath) {
    ifstream instream;
    instream.open(filepath);
    StreamArrayReader(&instream);
    instream.close();
}

Однако, это не разрешено в C ++. По этой причине мы можем определить метод закрытого друга следующим образом, который реализует то, что должен делать первый конструктор:

private:
  friend void init_stream_array_reader(StreamArrayReader *o, istream * is);

Теперь этот метод (потому что это друг) имеет доступ к закрытым полям o. Затем первый конструктор становится:

StreamArrayReader::StreamArrayReader(istream * is) {
    init_stream_array_reader(this, is);
}

Обратите внимание, что это не создает несколько копий для вновь созданных копий. Вторым становится:

StreamArrayReader::StreamArrayReader(char * filepath) {
    ifstream instream;
    instream.open(filepath);
    init_stream_array_reader(this, &instream);
    instream.close();
}

То есть вместо того, чтобы один конструктор вызывал другого, оба вызывают частного друга!

16
задан Larsenal 24 July 2009 в 19:01
поделиться

6 ответов

 SELECT Item.ID, Item.Name
ОТ Пункт
ГДЕ Item.ID IN (
 ВЫБЕРИТЕ ItemTag.ItemID
 ОТ ItemTag
 ГДЕ ItemTag.TagID = 57 ИЛИ ItemTag.TagID = 55)

или

 ВЫБРАТЬ Item.ID, Item.Name
ОТ Пункт
ВЛЕВО ПРИСОЕДИНИТЬСЯ к ItemTag НА ItemTag.ItemID = Item.ID
ГДЕ ItemTag.TagID = 57 ИЛИ ItemTag.TagID = 55
ГРУППА ПО ПУНКТУ.ID

SELECT  Item.ID, Item.Name
FROM    Item
JOIN    (
        SELECT DISTINCT ItemID
        FROMT  ItemTag
        WHERE  ItemTag.TagID = 57 OR ItemTag.TagID = 55
        ) tags
ON      tags.ItemID = Item.ID

, но этот немного менее эффективен, чем IN или EXISTS .

См. Эту статью в моем блоге для более подробного сравнения производительности:

17
ответ дан 30 November 2019 в 21:46
поделиться

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

4
ответ дан 30 November 2019 в 21:46
поделиться
SELECT Item.ID, Item.Name
...
GROUP BY Item.ID

Это недопустимый T-SQL. Item.Name должно появляться в предложении group by или в агрегатной функции, например SUM или MAX.

2
ответ дан 30 November 2019 в 21:46
поделиться

Практически невозможно (если только вы не один из тех сумасшедших администраторов баз данных-гуру), что будет быстро, а что нет, не глядя на план выполнения и / или выполняя некоторые стресс-тесты. .

1
ответ дан 30 November 2019 в 21:46
поделиться

запустите это:

SET SHOWPLAN_ALL ON

затем запустите каждую версию запроса

, вы можете увидеть, возвращают ли они тот же план, а если нет, посмотрите TotalSubtreeCost в первой строке каждого и посмотрите, насколько они разные.

0
ответ дан 30 November 2019 в 21:46
поделиться

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

Второй выигрывает по производительности.

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

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

0
ответ дан 30 November 2019 в 21:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: