我正在加入三张桌子' customer',' customer_address'和国家'使用左连接,因为我允许客户拥有一个或没有地址。 目前我有13k +客户,查询大约需要40秒。我尝试了内部联接,但在这种情况下,我没有让客户没有地址。 ' ON'中的所有列被编入索引,但它并没有太大的区别。 这是我的疑问:
SELECT DISTINCT *,
CASE
WHEN customer_address.customerid is NULL THEN customer.customerid
ELSE customer_address.customerid
END as customerid,
CASE
WHEN address1 = '' THEN 'NA'
ELSE address1
END as address1
FROM customer
LEFT JOIN customer_address ON customer.customerid = customer_address.customerid
LEFT JOIN country ON country.id = customer_address.country
WHERE deleted='0'
ORDER BY customer.customerid
DESC
LIMIT 0, 10
任何帮助将不胜感激
编辑:
这是'解释'对于三个表:
Field Type Null Key Default Extra
customerid int(12) NO PRI NULL auto_increment
forename varchar(128) YES NULL
surname varchar(128) YES NULL
company varchar(64) YES NULL
tel varchar(32) YES NULL
tel2 varchar(32) YES NULL
fax varchar(32) YES NULL
mob varchar(32) YES NULL
email varchar(255) YES NULL
date_reg date YES NULL
last_update datetime YES NULL
deleted int NO
Field Type Null Key Default Extra
addressid varchar(12) NO PRI
customerid varchar(12) YES MUL NULL
address1 varchar(128) YES NULL
address2 varchar(128) YES NULL
town varchar(128) YES NULL
county varchar(128) YES MUL NULL
postcode varchar(12) YES NULL
country int(12) YES NULL
address_date datetime YES NULL
isprimary int NO not
Field Type Null Key Default Extra
id int(12) NO PRI 0
country varchar(255) YES NULL
目前没有删除!=' 0'
编辑2:
查询说明:
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE customer NULL ALL deleted NULL NULL NULL 13082 99.98 Using where; Using temporary; Using filesort
1 SIMPLE customer_address NULL ALL NULL NULL NULL NULL 9983 100.00 Using where; Using join buffer (Block Nested Loop)
1 SIMPLE country NULL eq_ref PRIMARY,id PRIMARY 4 db_name.customer_address.country 1 100.00 NULL
编辑3:
1 SIMPLE customer NULL index NULL customerid 4 NULL 1 10.00 Using where; Using temporary
1 SIMPLE customer_address NULL ALL NULL NULL NULL NULL 9983 100.00 Using where
1 SIMPLE country NULL eq_ref PRIMARY,id PRIMARY 4 db_name.customer_address.country 1 100.00 NULL
答案 0 :(得分:0)
你可以试试这个。您不需要使用第一个CASE语句,因为您永远不会将CustomerId作为NULL接收。我已经删除了ORDER BY子句,因为我假设它会提高查询性能(CustomerId是一个主键,用于显示记录在数据库中的物理排列方式。默认排列顺序为升序。)
SELECT DISTINCT *, C.customerid as customerid,
CASE
WHEN customer_address.address1 = '' THEN 'NA'
ELSE customer_address.address1
END as address1 from (select *
FROM customer where deleted='0' order by customerid DESC) AS C
LEFT JOIN customer_address ON C.customerid = customer_address.customerid
LEFT JOIN country ON country.id = customer_address.country
LIMIT 0, 10
答案 1 :(得分:0)
那么,您必须使用不使用任何索引的所有类型查询。其中一个甚至有可怕的文件存储,这是一个非常昂贵的操作。
在customer_address.customerid字段中添加索引。这将用于匹配customer_address表和主客户表中的记录。
列出要从查询中返回的列,不要使用*。例如,我不明白为什么你需要从客户和地址表中返回customerid。
摆脱第一个案例陈述。 customer.customerid字段将始终填充。
在customer表后添加索引提示,以使mysql考虑使用customerid索引进行排序:
...
FROM customer FORCE INDEX index_name_forcustomerid_field
...
您可能需要考虑增加join_buffer_size服务器变量,但是,首先添加索引应该会有很大帮助。