Optimize câu truy vấn

Các bác ơi, e có đoạn truy vấn sql viết ở dưới. Khi execute thì mất tận 4-5s mặc dù records trả về không nhiều lắm. Các bác giúp e optimize lại đoạn này được k ah ? thanks

DECLARE @SoPhieu NVARCHAR(50) = 'SO.68.10418'
DECLARE @BusinessId VARCHAR(30) = '46'

SELECT	
	TOP(30)
	T.ID AS IDPhieuBan,
	T.SoPhieu,
	T.NgayXuat,
	T.IDKhachHang,
	T.DiaChi,
	T.DienThoai,
	T.Kieu,
	T.TheGiamGia,
	k.MaKhachHang,
	k.TenKhachHang
FROM (
	SELECT TOP(10)
		c.ID,
		c.SoPhieu,
		c.NgayXuat,
		c.IDKhachHang,
		C.DiaChi,
		C.DienThoai,
		'SO' AS Kieu,
		ISNULL(c.TheGiamGia, 0) AS TheGiamGia
	FROM dbo.SaleOnline c WITH (NOLOCK)
	INNER JOIN kse_func_Accounting_GetTrangThaiDonHang() TT ON TT.TTHAI = C.TrangThaiPhieu
	WHERE c.SoPhieu LIKE N'%' + @SoPhieu + '%'
	AND c.BusinessId = @BusinessId
	UNION ALL
	SELECT TOP(10)
		c.ID,
		c.SoPhieu,
		c.NgayXuat,
		c.IDKhachHang,
		C.DiaChi,
		C.DienThoai,
		'BB' AS Kieu,
		0 AS TheGiamGia
	FROM dbo.SE_XuatBanBuon c  WITH (NOLOCK)
	INNER JOIN kse_func_Accounting_GetTrangThaiDonHang() TT ON TT.TTHAI = C.TrangThaiPhieu
	WHERE c.SoPhieu LIKE N'%' + @SoPhieu + '%'
	AND c.BusinessId = @BusinessId
	UNION ALL
	SELECT TOP(10)
		c.ID,
		c.SoPhieu,
		c.NgayXuat,
		c.IDKhachHang,
		C.DiaChi,
		C.DienThoai,
		'BL' AS Kieu,
		ISNULL(c.TheGiamGia, 0) AS TheGiamGia
	FROM dbo.SE_XuatBanLe c  WITH (NOLOCK)
	INNER JOIN kse_func_Accounting_GetTrangThaiDonHang() TT ON TT.TTHAI = C.TrangThaiPhieu
	WHERE c.SoPhieu LIKE N'%' + @SoPhieu + '%'
	AND c.BusinessId = @BusinessId
) T 
INNER JOIN dbo.DM_KhachHang k WITH (NOLOCK) ON T.IDKhachHang = k.ID 
WHERE k.BusinessId = @BusinessId

Bạn format lại code để dễ nhìn.

Bạn kiểm tra 4 - 5s đó bằng cách nào?

Human formatter :kissing_smiling_eyes:

DECLARE @SoPhieu NVARCHAR(50) = 'SO.68.10418'
DECLARE @BusinessId VARCHAR(30) = '46'

SELECT TOP(30)
  T.ID AS IDPhieuBan, T.SoPhieu, T.NgayXuat,
  T.IDKhachHang, T.DiaChi, T.DienThoai, T.Kieu, T.TheGiamGia,
  k.MaKhachHang, k.TenKhachHang
FROM (
  SELECT TOP(10)
    c.ID, c.SoPhieu, c.NgayXuat, c.IDKhachHang,
    C.DiaChi, C.DienThoai,
    'SO' AS Kieu,
    ISNULL(c.TheGiamGia, 0) AS TheGiamGia
  FROM dbo.SaleOnline c WITH (NOLOCK)
  INNER JOIN
    kse_func_Accounting_GetTrangThaiDonHang() TT ON TT.TTHAI = C.TrangThaiPhieu
  WHERE
    c.SoPhieu LIKE N'%' + @SoPhieu + '%' AND c.BusinessId = @BusinessId

  UNION ALL

  SELECT TOP(10)
    c.ID, c.SoPhieu, c.NgayXuat, c.IDKhachHang,
    C.DiaChi, C.DienThoai,
    'BB' AS Kieu,
    0 AS TheGiamGia
  FROM dbo.SE_XuatBanBuon c WITH (NOLOCK)
  INNER JOIN
    kse_func_Accounting_GetTrangThaiDonHang() TT ON TT.TTHAI = C.TrangThaiPhieu
  WHERE
    c.SoPhieu LIKE N'%' + @SoPhieu + '%' AND c.BusinessId = @BusinessId
  
  UNION ALL

  SELECT TOP(10)
    c.ID, c.SoPhieu, c.NgayXuat, c.IDKhachHang,
    C.DiaChi, C.DienThoai,
    'BL' AS Kieu,
    ISNULL(c.TheGiamGia, 0) AS TheGiamGia
  FROM dbo.SE_XuatBanLe c WITH (NOLOCK)
  INNER JOIN
    kse_func_Accounting_GetTrangThaiDonHang() TT ON TT.TTHAI = C.TrangThaiPhieu
  WHERE
    c.SoPhieu LIKE N'%' + @SoPhieu + '%' AND c.BusinessId = @BusinessId
) T 
INNER JOIN
  dbo.DM_KhachHang k WITH (NOLOCK) ON T.IDKhachHang = k.ID 
WHERE
  k.BusinessId = @BusinessId
4 Likes

Có bác Hung vừa format ở dưới rồi a ơi , thanks bác Hung nhé :smiley: , đoạn e viết là excecute (F5) luôn đó a , xong đợi khi ra kết quả thì xem time thực thi ở góc dưới cũng bên phải ý

Chạy execute plan trước đễ biết nó tốn thời gian đoạn nào đã -.-

2 Likes

Em chạy như bác nói, thấy có đoạn query 3 nó bảo cost 98 % , giờ sao nữa hả bác ơi :frowning:

Theo bác gọn lại ntn vậy ? 3 table là # nhau , đoạn đó là e có join với 1 function để lấy bản ghi phù hợp với trạng thái trong function đó, muốn gộp nhắm nhưng chưa gộp dư nào ? chả nhẽ tạo table temp :smiley:

1 Like

Hàm này gọi mỗi lần ra giá trị khác nhau á :cry:
Chắc tạo temp gì đó như bạn rồi.

kse_func_Accounting_GetTrangThaiDonHang()
3 Likes

E đã chuyển function đó lên table temp nhưng kq vẫn không thay đổi bác ah :frowning:

Hix, mình bí rồi, để mình mời cao nhân đắc đạo.

3 Likes
LIKE N'%' + @SoPhieu + '%'

LIKE thường có range rộng hơn và cost cao hơn =. Bạn thử chuyển coi.

SELECT ngoài cùng bạn dùng select all, TOP(30) gì nữa cho mệt

Chuẩn nhất thì là phải ‘=’ nhưng UI đa phần họ có bao giờ nhập đúng đâu a nên chỗ đó e không thể thay thế kiểu # được bác ơi, chuyển sang ‘=’ thì chưa đến 1s luôn ý chứ :slight_smile:

Bác mời cao nhân giúp e nhá, thanks bác nhiều

1 Like

Code khó nhìn quá -.-
sửa lai code với WITH thay cho subquery xem
nhớ đánh index các column cần thiết
bonus các bước turning Sql:

2 Likes

Index thì e đánh rồi, cũng chuyển table tem thành dùng with như bác nói cũng k khá hơn bác ơi :frowning: , mô hình tháp bác gửi , bác có tài liệu hướng dẫn k gửi e với

Cái mô hình này bên oracle:
http://www.dba-oracle.com/art_sql_tune.htm

1 Like
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?