簡體   English   中英

MySQL性能不佳

[英]MySQL poor performance

我的應用程序的一部分存在一個大問題。 我使用的是SQLAlchemy和MySQL的組合,大多數情況下都可以正常工作,但是有一個問題可以永久加載,有時甚至需要5-6分鍾才能加載客戶列表。 該表大約有3000行,對於數據庫標准來說應該很小,而我在一個稍大的表(25k行)上進行了簡單的聯接。

SQL Alchemy中的查詢如下:

last_inv = db.session.query(Sales.id).order_by(Sales.invoice_date.desc()).filter(Customer.email == Sales.email).limit(1).correlate(Customer)
results = db.session.query(Customer, last_inv.as_scalar()).filter_by(archive=0)

原始SQL如下所示:

SELECT customer.id AS customer_id
     , customer.first_name AS customer_first_name
     , customer.middle_name AS customer_middle_name
     , customer.last_name AS customer_last_name
     , customer.email AS customer_email
     , customer.password AS customer_password
     , customer.address1 AS customer_address1
     , customer.address2 AS customer_address2
     , customer.city AS customer_city
     , customer.state AS customer_state
     , customer.zip AS customer_zip
     , customer.country AS customer_country
     , customer.phone AS customer_phone
     , customer.cell_phone AS customer_cell_phone
     , customer.current_plan AS customer_current_plan
     , customer.minutes_current_plan AS customer_minutes_current_plan
     , customer.orig_sales_id AS customer_orig_sales_id
     , customer.sales_id AS customer_sales_id
     , customer.team_id AS customer_team_id
     , customer.refill_date AS customer_refill_date
     , customer.minutes_refill_date AS customer_minutes_refill_date
     , customer.active AS customer_active
     , customer.archive AS customer_archive
     , customer.imported AS customer_imported
     , customer.ipaddress AS customer_ipaddress
     , customer.auto_renewal AS customer_auto_renewal
     , customer.signup_date AS customer_signup_date
     , customer.esn AS customer_esn
     , customer.last_update_date AS customer_last_update_date
     , customer.last_update_by AS customer_last_update_by
     , customer.notes AS customer_notes
     , customer.current_pin AS customer_current_pin
     , customer.minutes_current_pin AS customer_minutes_current_pin
     , customer.security_pin AS customer_security_pin
     , (SELECT sales.id  
          FROM sales 
         WHERE customer.email = sales.email 
         ORDER 
            BY sales.invoice_date DESC LIMIT 1) AS anon_1 
  FROM customer 
 WHERE customer.team_id = 1 
   AND customer.archive = 0

我嘗試了很多事情,但這確實開始使我感到絕望。 這都是在亞馬遜上運行的,運行時htop顯示mysql的100%使用率。 phpmyadmin,HeidiSQL上的查詢的探查器顯示,此操作在不到兩秒的時間內完成(當未在cahce中被擊中時),因此它不是導致此問題的實際查詢(據我所知)。

這是EXPLAIN顯示的內容:

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   PRIMARY customer    ALL NULL    NULL    NULL    NULL    3621    Using where
2   DEPENDENT SUBQUERY  sales   ALL NULL    NULL    NULL    NULL    22619   Using where;    Using filesort

來自phpmyadmin的Profiler在這里 ,視覺表示在這里

我正在EC2上運行一個m1.small實例,具有1650MB的RAM。

我已經運行mysqlprofiler為好,這里是結果之前之后,我也做了優化。 我的my.cnf文件在這里

我嘗試在表上運行OPTIMIZE ,但是由於某些原因,未優化的表的數量始終為98,所以我想我做錯了。 為此使用了腳本以及phpmyadmin中的原始sql,但均未成功。

嘗試創建此多列索引,這將加快查詢速度:

CREATE INDEX sales_eml_invdat ON sales( email, invoice_date );

甚至三列

CREATE INDEX sales_eml_invdat_id ON sales( email, invoice_date, id );

但僅在id不是主鍵列的情況下。
如果id是主鍵,那么前一個索引就足夠了。

----編輯------

對不起,我忘記了MySql不如其他DBMS聰明。
它不能單獨檢測到這種情況,必須明確地告訴他如何去做。
請將子查詢改寫為:

SELECT sales.id  
FROM sales 
WHERE customer.email = sales.email 
ORDER BY sales.email DESC, sales.invoice_date DESC 
LIMIT 1

此更改使MySql可以使用( email, invoice_date )索引來跳過文件排序,請嘗試一下。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM