2014-04-23 20 views
8

Tôi có một bảng trong Sql Azure chứa khoảng 6M hàng. Tôi muốn tạo chỉ mục mới cho nó. cmd giống như:sql azure time query query

CREATE NONCLUSTERED INDEX [INDEX1] ON [dbo].Table1 
(
    [Column1] ASC, 
    [Column2] ASC, 
    [Column3] ASC, 
    [Column4] ASC 
) 
INCLUDE ([Column5],[Column6]) 

Và sau khoảng 15 phút, một lỗi xảy ra

"Msg 10054, Level 20, State 0, Line 0

A transport-level error has occurred when receiving results from the server. (provider: TCP Provider, error: 0 - An existing connection was forcibly closed by the remote host.)"

tôi đã cố gắng nhiều lần, có những lỗi tương tự. Nhưng tôi đã thực hiện các truy vấn tốn thời gian khác, như:

Insert into table1(Col1,Col2,Col3) select Col1,Col2,Col3 from table2

Mất 20 phút và trả về thành công.

Các truy vấn được thực hiện trong cùng một Sql Azure DB. Tôi không biết chuyện gì đang diễn ra ở đây. Bất cứ ai có thể giúp đỡ? Cảm ơn!

+0

Bạn có thể thử tạo bảng mới với chỉ mục và sau đó di chuyển các hàng từ bảng cũ sang bảng mới và sau đó xóa bảng cũ và đổi tên bảng mới? –

Trả lời

8

Tôi đã gặp sự cố tương tự với bảng chứa hàng 100M và liên hệ với bộ phận Hỗ trợ của Microsoft. Đây là câu trả lời tôi nhận được:

The reason why you can’t create the index on your table is that you are facing a limitation on the platform that prevents to have transactions larger than 2GB.

The creation of an index is a transactional operation that relies on the transaction log to execute the move of the table pages. More rows in a table means more pages to put in the T-Log. Since your table contains 100 million of records (which is quite a big number), it is easy for you to hit this limit.

In order to create the index we need to change the approach. Basically we are going to use a temporary(staging) table to store the data while you create the index on the source table, that you would have previously cleared from data.

Action Plan:

  1. Create a staging table identical to the original table but without any index (this makes the staging table a heap)
  2. move the data from the original table to a staging table (the insert is faster because the staging table is a heap)
  3. empty the original table
  4. create the index on the original table (this time the transaction should be almost empty)
  5. move back data from staging table to original table (this would take some time, as the table contains indexes)
  6. delete the staging table

Chúng đề nghị sử dụng BCP để di chuyển dữ liệu giữa bảng dàn và bảng gốc.

Khi nhìn vào bảng event_log ...

select * from sys.event_log 
where database_name ='<DBName>' 
and event_type <> 'connection_successful' 
order by start_time desc 

.. tôi thấy thông báo lỗi này:

The session has been terminated because of excessive transaction log space usage. Try modifying fewer rows in a single transaction.

+3

Nếu điều này thực sự là cách tiếp cận tốt nhất có sẵn để tạo ra một chỉ số lớn trên Azure thì tôi chỉ mất rất nhiều tự tin vào nó. – usr

+0

Chúng tôi hiện đang sử dụng SQL Server trên máy ảo Azure IaaS thay thế. Nó hoạt động chính xác như một môi trường tiền đề, không giới hạn kích thước nhật ký giao dịch. – andersh

+0

Bài viết này, https://alexandrebrisebois.wordpress.com/2013/09/29/creating-nonclustered-indexes-on-massive-tables-in-windows-azure-sql-database/, đề xuất sử dụng tùy chọn ONLINE = ON để tránh giới hạn tới hạn này đối với SQL Azure. –

2

Cám ơn trả lời! Trên thực tế, tôi tìm thấy nguyên nhân gốc rễ.
Có một giải pháp cho nó, đặt ONLINE = ON, ở chế độ trực tuyến, tác vụ tạo chỉ mục sẽ được chia thành nhiều tác vụ nhỏ nên T-Log sẽ không vượt quá 2GB.
Nhưng có một giới hạn, 'cột bao gồm' của chỉ mục tạo lệnh không thể là đối tượng có kích thước không giới hạn, như nvarchar (tối đa), nếu như vậy lệnh sẽ thất bại ngay lập tức.

Vì vậy, trong Sql Azure, cho một hoạt động chỉ số tạo như sau:

CREATE NONCLUSTERED INDEX [INDEX1] ON [dbo].Table1 
(
    [Column1] ASC, 
    [Column2] ASC, 
    [Column3] ASC, 
    [Column4] ASC 
) 
INCLUDE ([Column5],[Column6]) 

lấy hành động sau đây, nếu trước đó đã thất bại.
1.tạo chỉ mục bằng cách sử dụng 'online = on'
2.if # 1 thất bại, có nghĩa là cột 5 hoặc cột 6 là nvarchar (tối đa), truy vấn kích thước bảng, nếu < 2GB, trực tiếp tạo chỉ mục bằng cách sử dụng online = off.
3.if # 2 thất bại, có nghĩa là kích thước bảng> 2GB, sau đó không có cách đơn giản để tạo chỉ mục mà không có bảng tạm thời tham gia, phải hành động như ahkvk trả lời.

+0

Đây là một bài viết hay về chủ đề làm rõ gợi ý tuyệt vời của bạn: https://alexandrebrisebois.wordpress.com/2013/09/ 29/tạo-nonclustered-chỉ mục-trên-lớn-bảng-trong-windows-azure-sql-cơ sở dữ liệu/ –

+0

Chỉ cần cập nhật; gợi ý của bạn dẫn tôi đến giải pháp. Đối với tôi - và hy vọng những người khác - đây là câu trả lời được chấp nhận. +1 –

+0

Điều này làm việc cho tôi. Trên một nỗ lực thứ hai ít nhất. BAO GỒM ([Cột 5], [Cột 6]) VỚI (ONLINE = ON); – McGaz