-3

I have 2 tables, trans_details_sell and trans_details_buy, and both have 400 millions rows each. These 2 table are linked up with a unique column call cdr_id.

A 3rd table is deal_master, which is the master table only have about 300 master records.

My query will be using deal_master to link up trans_details_sell to get the revenue and at the mean time using trans_details_sell to link up trans_details_buy to get the cost (with cdr_id).

  • deal_master is using lcr_zone and customer_interconnect to link with trans_details_sell and its columns, lcr_zone and sig_netgroup.

  • trans_details_sell has clustered primary key (lcr_zone, sig_netgroup, cdr_id)

  • trans_details_buy has clustered primary key (lcr_zone, sig_netgroup, cdr_id)

Both tables have the same data structure but 1 for sell records one for buy records, and also both having CDR_ID as non-clustered unique index.

My main query, when only involve 2 table which is deal_master and trans_details_sell, the speed is ok (to get the revenue), but when add in trans_details_buy to get the cost, it will be extremely slow.

My SQL looks like this:

SELECT 
    m.agreement_no, m.status, m.sales_person, m.swap_carrier, 
    m.swap_commitment, m.zone, m.lcr_zone, m.customer_interconnect, 
    SUBSTRING(CAST(m.start_pos AS nvarchar), 1, 4) + '-' +
       SUBSTRING(CAST(m.start_pos AS nvarchar), 5, 2) + '-' +
       SUBSTRING(CAST(m.start_pos AS nvarchar), 7, 2) start_date, 
    SUBSTRING(CAST(m.end_pos AS nvarchar), 1, 4) + '-' +
       SUBSTRING(CAST(m.end_pos AS nvarchar), 5, 2) + '-' +
       SUBSTRING(CAST(m.end_pos AS nvarchar), 7, 2) end_date, 
    m.target_minutes, m.target_sell_rate, m.target_buy_rate, 
    m.target_sales, m.target_cost, m.target_profit, 
    SUM(s.quantized_duration) / 60 DG_minute, 
    SUM(s.charge) DG_sales, SUM(b.charge) DG_cost
FROM 
    deal_master m, trans_details_sell s, trans_details_buy b
WHERE
    m.lcr_zone = s.lcr_zone 
    AND m.customer_interconnect = s.sig_netgroup 
    AND m.swap_commitment = 'Sell' 
    AND s.cdr_id = b.cdr_id 
    AND s.start_position BETWEEN m.start_pos AND m.end_pos
GROUP BY
    m.agreement_no, m.status, m.sales_person, m.swap_carrier, 
    m.swap_commitment, m.zone, m.lcr_zone, m.customer_interconnect, 
    m.start_pos, m.end_pos, m.target_minutes, m.target_sell_rate, 
    m.target_buy_rate, m.target_sales, m.target_cost, m.target_profit
ORDER BY 
    1

deal_master :

CREATE TABLE [dbo].[deal_master]
(
    [agreement_no] [nchar](10) NOT NULL,
    [status] [nvarchar](20) NOT NULL,
    [sales_person] [nvarchar](50) NOT NULL,
    [swap_carrier] [nvarchar](100) NOT NULL,
    [start_pos] [numeric](18, 0) NOT NULL,
    [end_pos] [numeric](18, 0) NOT NULL,
    [swap_commitment] [nvarchar](10) NOT NULL,
    [zone] [nvarchar](200) NOT NULL,
    [target_minutes] [numeric](10, 0) NULL,
    [target_sell_rate] [decimal](13, 11) NULL,
    [target_buy_rate] [decimal](13, 11) NULL,
    [supplier_interconnect] [nvarchar](200) NOT NULL,
    [customer_interconnect] [nvarchar](200) NOT NULL,
    [target_sales] [numeric](10, 2) NULL,
    [target_cost] [numeric](10, 2) NULL,
    [target_profit] [numeric](10, 2) NULL,
    [partner] [nvarchar](50) NULL,
    [lcr_zone] [nvarchar](100) NOT NULL,
 CONSTRAINT [pk_deal_master] PRIMARY KEY CLUSTERED 
(
    [lcr_zone] ASC,
    [customer_interconnect] ASC,
    [supplier_interconnect] ASC,
    [start_pos] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO

trans_details_sell:

CREATE TABLE [dbo].[trans_details_sell]
(
    [cdr_id] [nchar](12) NOT NULL,
    [rate] [nvarchar](50) NOT NULL,
    [zone] [nvarchar](50) NOT NULL,
    [charge] [decimal](13, 11) NOT NULL,
    [quantized_duration] [numeric](8, 0) NOT NULL,
    [sig_carrier_group] [nvarchar](50) NOT NULL,
    [sig_netgroup] [nvarchar](50) NOT NULL,
    [lcr] [nvarchar](100) NOT NULL,
    [lcr_zone] [nvarchar](50) NOT NULL,
    [per_min_chg] [decimal](13, 11) NOT NULL,
    [trans_type] [nvarchar](10) NOT NULL,
    [start_position] [numeric](18, 0) NOT NULL,
    [end_position] [numeric](18, 0) NOT NULL,
    [filename] [nvarchar](50) NOT NULL,
 CONSTRAINT [pk_trans_details_sell] PRIMARY KEY CLUSTERED 
(
    [lcr_zone] ASC,
    [sig_netgroup] ASC,
    [cdr_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO

trans_details_buy:

CREATE TABLE [dbo].[trans_details_sell]
(
    [cdr_id] [nchar](12) NOT NULL,
    [rate] [nvarchar](50) NOT NULL,
    [zone] [nvarchar](50) NOT NULL,
    [charge] [decimal](13, 11) NOT NULL,
    [quantized_duration] [numeric](8, 0) NOT NULL,
    [sig_carrier_group] [nvarchar](50) NOT NULL,
    [sig_netgroup] [nvarchar](50) NOT NULL,
    [lcr] [nvarchar](100) NOT NULL,
    [lcr_zone] [nvarchar](50) NOT NULL,
    [per_min_chg] [decimal](13, 11) NOT NULL,
    [trans_type] [nvarchar](10) NOT NULL,
    [start_position] [numeric](18, 0) NOT NULL,
    [end_position] [numeric](18, 0) NOT NULL,
    [filename] [nvarchar](50) NOT NULL,
 CONSTRAINT [pk_trans_details_sell] PRIMARY KEY CLUSTERED 
(
    [lcr_zone] ASC,
    [sig_netgroup] ASC,
    [cdr_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Alan Chew
  • 35
  • 1
  • 3
  • 1
    You mention SQL Server in your question, but you tagged the question [tag:mysql]. Which database brand are you really using? Tagging your question accurately will help get the attention of people who are able to give the best answer for the database you are using. – Bill Karwin Aug 06 '22 at 15:26
  • 1
    Please publish table definitions and execution plan as text. – P.Salmon Aug 06 '22 at 15:29
  • I know I can merger trans_details_sell and trans_details_buy to 1 table, but for some reasons I opt not to, so is there any method to speed it up? Many thanks – Alan Chew Aug 06 '22 at 15:59
  • Is `cdr_id` unique? Is it indexed? – David Browne - Microsoft Aug 06 '22 at 16:06
  • 2
    @DavidBrowne-Microsoft, although not in the DDL, he did mention the buy/sell tables "both having CDR_ID as non-clustered unique index." – Dan Guzman Aug 06 '22 at 16:31
  • 1
    _both having CDR_ID as non-clustered unique index_ This belongs in your DDL, not as a comment buried in your description. If that is the case, then the primary key serves no useful purpose except for clustering. – SMor Aug 06 '22 at 16:39
  • 1
    [Bad habits to kick : using old-style JOINs](https://sqlblog.org/2009/10/08/bad-habits-to-kick-using-old-style-joins) - that old-style *comma-separated list of tables* style was replaced with the *proper* ANSI `JOIN` syntax in the ANSI-**92** SQL Standard (**30 years!!** ago) and its use is discouraged – marc_s Aug 06 '22 at 18:13
  • [Bad habits to kick : declaring VARCHAR without (length)](https://sqlblog.org/2009/10/09/bad-habits-to-kick-declaring-varchar-without-length) - you should **always** provide a length for any `varchar` variables (here in your `CAST` statements) and parameters that you use – marc_s Aug 06 '22 at 18:14

1 Answers1

0

The query only needs charge from trans_detail_buy, so add it as an included column on the unique index on clr_id

create unique index ix_clr_id 
 on trans_details_buy(clr_id) 
 include (charge)

Otherwise the clr_id is used to look up the row locator (lcr_zone, sig_netgroup, cdr_id) which is used to seek the clustered index to find the charge.

Or if they _buy and _sell always have the same lcr_zone and sig_netgroup for each clr_id, then join trans_details_buy on all three columns to bypass the index on clr_id.

David Browne - Microsoft
  • 80,331
  • 6
  • 39
  • 67
  • 1
    Thanks for your good efforts. After I added and included, it take 5min and 24sec to come out the result. It is still too long time, I think I will create an additional field which is [charge] field to the trans_details_sell table. – Alan Chew Aug 07 '22 at 08:26