优化多个表的连接

时间:2016-08-04 12:01:22

标签: sql-server query-optimization inner-join

如果表格结构如下图所示,如何优化下面提到的查询的效果

Pic Showing The Table Structure

select CounterID, OutletTitle, CounterTitle
from(
    select OutletID, Text as OutletTitle 
    from Outlets as q1
    inner join 
    TranslationTexts as tt 
    on q1.TitleID=tt.TranslationID
    where tt.Locale='ar-SA' and q1.CompanyID=311 and q1.OutletID=8 --Locale & CompanyID & OutletID
    ) as O    
inner join    
(
    select CounterID, Text as CounterTitle, OutletID
    from Counters as q1
    inner join 
    TranslationTexts as tt 
    on q1.TitleID=tt.TranslationID
    where tt.Locale='ar-SA' and q1.OutletID=8 --Locale & OutletID   
) as C
on O.OutletID=C.OutletID

3 个答案:

答案 0 :(得分:2)

您应该尝试此请求:

DataTable CommunicationTable = new DataTable();
Thread listeningThread;
public Form1()
{
    InitializeComponent();
    CommunicationTable.Columns.Add("addressIP", typeof(string));
    CommunicationTable.Columns.Add("port", typeof(int));
    CommunicationTable.Rows.Add("127.0.0.1", 1100);

    // Notice this assignment:
    dataGridView1.DataSource = CommunicationTable;

    listeningThread = new Thread(() => {
        // UDP listener emulator.
        // Replace with actual code but don't forget the Invoke()
        for (int i = 0; i < 10; i++)
        {
            Invoke((MethodInvoker)delegate {
                CommunicationTable.Rows.Add("127.0.0.1", 1024 + i); });
            Thread.Sleep(300);
        }
    });
    listeningThread.Start();
}

要获得更好的性能,可以在3个表上添加一些索引。

答案 1 :(得分:1)

这是一种不同的方法。我不能说性能有所提高,因为这取决于很多其他事情,但我相信它是一个等同版本,更容易阅读。

SELECT
    C.CounterID
    , tt.Text AS OutletTitle
    , tt.Text AS CounterTitle
FROM
    Outlets AS q1
    INNER JOIN TranslationTexts AS tt ON q1.TitleID=tt.TranslationID
    INNER JOIN Counters C ON c.OutletID=q1.OutletID
    INNER JOIN TranslationTexts AS tt2 ON tt2.TranslationID=tt.TranslationID AND tt2.Locale=tt.Locale
WHERE
    tt.Locale='ar-SA' and q1.CompanyID=311 and q1.OutletID=8;

答案 2 :(得分:1)

问题是你想要优化什么......可读性(和可维护性)和/或性能?

大多数人在撰写查询时都有自己的“风格”。我更喜欢下面的那个,但是对于服务器它可能看起来一样,并且很可能系统将具有完全相同的“工作量”以获得数据,即使它看起来与我们人类不同。我建议稍微谷歌并学习如何解释查询计划。

SELECT q2.CounterID, 
       tt1.Text as OutletTitle, 
       tt2.Text as CounterTitle

FROM Outlets as q1

INNER JOIN Counters as q2 
        ON q2.OutletID = q1.OutletID

INNER JOIN TranslationTexts as tt1
        ON tt1.TranslationID = q1.TitleID 
       AND tt1.Locale        = 'ar-SA'

INNER JOIN TranslationTexts as tt2 
        ON tt2.TranslationID = q2.TitleID
       AND tt2.Locale        = 'ar-SA' 

WHERE q1.CompanyID = 311 
  AND q1.OutletID  = 8 

我注意到的一点是,您将CompanyIDOutletID作为Outlets表的过滤器传递。由于OutletID是该表的主键,我想知道您是否真的需要CompanyID上的过滤器。充其量它会消除记录,因为它是错误的公司,但不知何故,我的印象是你已经知道正确的CompanyID

至于表现,我会建议这些指数

CREATE INDEX idx_Locale ON TranslationTexts (Locale, Translation_id)
CREATE INDEX idx_CompanyID ON Outlets (CompanyID) INCLUDE (TitleID, OutletID)

您很可能甚至可以在Local UNIQUE索引上创建该索引,使其更好用。