2013-08-07 46 views
11

tôi chạy truy vấn sau đây từ vỏ của tôi:MySQL Query với số lượng lớn các hồ sơ bị giết

mysql -h my-host.net -u myuser -p -e "SELECT component_id, parent_component_id FROM myschema.components comp INNER JOIN my_second_schema.component_parents related_comp ON comp.id = related_comp.component_id ORDER BY component_id;" > /tmp/IT_component_parents.txt 

Các truy vấn chạy trong một thời gian dài và sau đó bị giết.

Tuy nhiên, nếu tôi thêm LIMIT 1000, thì truy vấn sẽ chạy đến cuối và đầu ra được ghi trong tệp.

tôi tiếp tục điều tra và tìm thấy (sử dụng COUNT (*)) mà tổng số lượng hồ sơ sẽ được trả lại là 239553163.

Một số thông tin về máy chủ của tôi là ở đây:

MySQL 5.5.27

+----------------------------+----------+ 
    | Variable_name    | Value | 
    +----------------------------+----------+ 
    | connect_timeout   | 10  | 
    | delayed_insert_timeout  | 300  | 
    | innodb_lock_wait_timeout | 50  | 
    | innodb_rollback_on_timeout | OFF  | 
    | interactive_timeout  | 28800 | 
    | lock_wait_timeout   | 31536000 | 
    | net_read_timeout   | 30  | 
    | net_write_timeout   | 60  | 
    | slave_net_timeout   | 3600  | 
    | wait_timeout    | 28800 | 
    +----------------------------+----------+ 

Dưới đây là NHÀ NƯỚC của truy vấn như tôi theo dõi:

copying to tmp table on disk 
    sorting results 
    sending data 
    writing to net 
    sending data 
    writing to net 
    sending data 
    writing to net 
    sending data ... 
    KILLED 

Có đoán xem có gì sai ở đây không?

Trả lời

1

Điều gì là sai khi bạn đang trả lại 239 553 163 hàng dữ liệu! Đừng ngạc nhiên, phải mất rất nhiều thời gian để xử lý. Trên thực tế, phần dài nhất có thể rất tốt sẽ gửi kết quả được đặt lại cho khách hàng của bạn.

Reuduce tập kết quả (bạn có thực sự cần tất cả các hàng này không?). Hoặc cố gắng để xuất dữ liệu theo lô nhỏ hơn:

mysql -h my-host.net -u myuser -p -e "SELECT ... LIMIT 10000, 0" >> dump.txt 
mysql -h my-host.net -u myuser -p -e "SELECT ... LIMIT 10000, 10000" >> dump.txt 
+0

Tôi đã có suy nghĩ đó để chia kết quả thành các phần nhỏ hơn. Nhưng cố gắng để xem nếu có một workaround để có được rằng thực hiện trong một shot :) Vâng, tôi cần tất cả các hàng. Nó được yêu cầu bởi nhiệm vụ mà tôi đang cố gắng hoàn thành. Cảm ơn vì tiền hỗ trợ. –

+0

@ManmohanBishnoi Bạn đang kết nối với một máy chủ chia sẻ hay bạn sở hữu máy chủ DB? Trong trường hợp đầu tiên, máy chủ lưu trữ có thể đã thực hiện tốt một cái gì đó mà giết chết các truy vấn dài (tôi nghĩ đó là những gì "KILLED" thông báo có nghĩa là). Chia sẻ máy chủ có thể (hy vọng;) thực hiện những điều như vậy để bảo vệ hệ thống của họ một lần nữa các cuộc tấn công giống như DoS. – RandomSeed

+0

Đây là một Instance lớn của Amazon RDS. Tôi đã chạy truy vấn LONG cho INSERT/UPDATE với số lượng bản ghi tương tự. vì vậy tôi đoán tôi phải hỏi DBA của tôi về điều này. –

0

Bạn có thể muốn sử dụng OUTFILE cơ chế, nếu bạn đang đi để đổ một lượng lớn dữ liệu. Điều đó hoặc mysql_dump sẽ hiệu quả hơn nhiều (và OUTFILE có lợi ích khi không khóa bảng).

+0

Người dùng tôi có thông tin đăng nhập không có quyền FILE để OUTFILE sẽ không hữu ích ở đây. –

+0

Sau đó, đây là một cái gì đó để đối đầu với nhà cung cấp hosting vì đây là tùy chọn tốt nhất để chọn lô dữ liệu lớn cho một định dạng CSV hoặc định dạng khác. –

1

Giả sử bạn có nghĩa là 8 giờ khi bạn nói một thời gian dài, giá trị 28800 cho số wait_timeout của bạn khiến kết nối bị ngắt mà không hoạt động thêm trong 28.800 giây, tức là 8 giờ. Nếu bạn không thể tối ưu hóa câu lệnh để chạy trong chưa đầy 8 giờ, bạn nên tăng giá trị này.

Xem this page để biết thêm thông tin về biến số wait_timeout.

Biến số interactive_timeout được sử dụng cho các kết nối khách hàng tương tác, vì vậy nếu bạn chạy các truy vấn dài từ một phiên tương tác, đó là số bạn cần xem.

+0

Truy vấn bị giết sau 3100 giây. vì vậy tôi đoán các giá trị là đủ. –

+1

Như RandomSeed gợi ý, có thể có lệnh 'KILL' bên ngoài được quản trị viên hoặc một công việc; một sự kiện được lên lịch thường xuyên có thể chạy để kiểm tra các truy vấn chạy dài (nếu nó luôn là 3100 giây hoặc nếu nó là 3100 cộng hoặc trừ 180 giây hoặc một số giá trị tương tự khác, có thể là giveaway), chạy một cái gì đó như 'SELECT id FROM INFORMATION_SCHEMA. PROCESSLIST WHERE TIME> 3000 AND Command! = 'Sleep'' và giết các ID được trả về –

+0

có các truy vấn khác mất khoảng 13000 giây để hoàn thành và chúng hoạt động như mong đợi, vì vậy nó là một số tham số/biến khác mà chúng ta phải thay đổi để làm việc này. –

13

Máy khách mysql có thể hết bộ nhớ.

Sử dụng tùy chọn --quick để không đệm kết quả trong bộ nhớ.

0

Bạn đã nói trong nhận xét rằng phiên bản MySQL của bạn là trên RDS. Điều này có nghĩa là bạn không thể chạy truy vấn từ cùng một máy chủ, vì bạn không thể đăng nhập vào máy chủ RDS. Tôi đoán bạn có thể làm truy vấn này qua mạng WAN từ mạng nội bộ của bạn.

Bạn rất có thể gặp sự cố do mạng chậm. Trạng thái xử lý của bạn thường xuyên hiển thị "viết trên mạng" khiến tôi nghĩ đây là nút cổ chai của bạn.

Nút cổ chai của bạn cũng có thể là sắp xếp. Sắp xếp của bạn đang ghi vào bảng tạm thời và có thể mất nhiều thời gian cho một tập hợp kết quả lớn. Bạn có thể bỏ qua ORDER BY không?

Mặc dù vậy, tôi không mong đợi truy vấn bị giết ngay cả khi nó chạy trong 3100 giây trở lên. Tôi tự hỏi nếu DBA của bạn có một số công việc định kỳ giết chết các truy vấn dài hạn, chẳng hạn như pt-kill. Hỏi DBA của bạn.

Để giảm thời gian truyền mạng, bạn có thể thử sử dụng giao thức nén. Bạn có thể sử dụng các cờ --compress hoặc -C cho ứng dụng khách mysql (xem https://dev.mysql.com/doc/refman/5.7/en/mysql-command-options.html#option_mysql_compress)

Trên mạng chậm, tính năng nén có thể hữu ích. Ví dụ: đọc về một số so sánh ở đây: https://www.percona.com/blog/2007/12/20/large-result-sets-vs-compression-protocol/

Một cách khác là chạy truy vấn từ cá thể điểm EC2 chạy trong cùng một AZ làm phiên bản RDS của bạn. Mạng giữa hai trường hợp này sẽ nhanh hơn rất nhiều, do đó, nó sẽ không làm chậm trễ quá trình truyền dữ liệu của bạn. Lưu đầu ra truy vấn vào một tệp trên cá thể điểm EC2.

Khi kết quả truy vấn được lưu trên phiên bản EC2 của bạn, bạn có thể tải nó xuống máy cục bộ của mình, sử dụng scp hoặc một cái gì đó, nên có khả năng chịu đựng các mạng chậm hơn.

+0

Truy vấn được chạy giữa EC2 và RDS. ORDER BY là cần thiết cho truy vấn này. Tuy nhiên rất nhiều đã thay đổi kể từ khi tôi đăng câu hỏi này một thời gian trở lại. Chúng tôi có một cơ sở dữ liệu hoàn chỉnh mới chạy trên PostgreSQL. –

+0

Ah. Tôi nên kiểm tra ngày tháng của câu hỏi cẩn thận hơn. Điều này xuất hiện trong nguồn cấp dữ liệu của tôi 2 ngày trước, nhưng bốn năm trước, bạn đã hỏi nó. –

Các vấn đề liên quan