我一直在使用以下查询来搜索某些数据。如果有任何设计错误,我是一个新的。请原谅。
SELECT
j.applicant_uid,
j.job_id,u.id,
MAX(u.name),
ui.phone,
ui.fullname,
ui.img,
ui.address,
u.r_date,
r.sex,
r.present_salary,
w.working,
w.description,
e.institute_name,
e.exam_name,
ROUND(DATEDIFF(w.time_start, w.time_end) / 365.25) AS experience,
ROUND(DATEDIFF(CURDATE(),r.dob) / 365.25) AS age,
r. preferred_district,
e.major_group ,
w.compnay_name,
w.designation,
j.ukey
FROM job_apply as j
INNER JOIN users u ON j.applicant_uid = u.id
INNER JOIN resume r ON j.applicant_uid = r.uid
INNER JOIN work_history w ON j.applicant_uid = w.uid
INNER JOIN education e ON j.applicant_uid = e.uid
INNER JOIN user_other_info ui ON j.applicant_uid = ui.uid
WHERE `j.job_id`='131'
AND `r.sex` LIKE '%1%'
AND `r.preferred_district` LIKE '%14%'
AND `w.description` LIKE '%brac%'
OR `e.exam_name` LIKE '%brac%'
OR `w.compnay_name` LIKE '%brac%'
OR `w.designation` LIKE '%brac%'
OR `e.institute_name` LIKE '%brac%'
GROUP BY `u.id`
HAVING `experience` >= '1'
AND `r.present_salary` BETWEEN '15000' AND '20000'
但它需要大约30.017秒。如何减少查询时间?可能是什么原因?我已经添加了别名。
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(500) NOT NULL,
`role_type` int(11) NOT NULL,
`user_type` int(3) NOT NULL,
`umail` varchar(100) NOT NULL,
`user_pass` varchar(100) NOT NULL,
`block` int(2) NOT NULL DEFAULT '0',
`r_date` date NOT NULL,
`u_date` date NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4560 DEFAULT CHARSET=latin1
这是简历表:
CREATE TABLE `resume` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`uid` int(11) NOT NULL,
`career_objective` varchar(5000) CHARACTER SET utf8 NOT NULL,
`father` varchar(100) CHARACTER SET utf8 NOT NULL,
`mother` varchar(100) CHARACTER SET utf8 NOT NULL,
`dob` date NOT NULL DEFAULT '0000-00-00',
`birth_place` varchar(100) CHARACTER SET utf8 NOT NULL,
`nationality` varchar(100) CHARACTER SET utf8 NOT NULL,
`sex` varchar(50) CHARACTER SET utf8 NOT NULL,
`looking_for` int(3) NOT NULL,
`present_salary` varchar(100) CHARACTER SET utf8 NOT NULL,
`expected_salary` varchar(10) CHARACTER SET utf8 NOT NULL,
`preferred_category` varchar(10) CHARACTER SET utf8 NOT NULL,
`preferred_district` varchar(10) CHARACTER SET utf8 NOT NULL,
`declaration` varchar(1000) CHARACTER SET utf8 NOT NULL,
`facebook_link` varchar(1000) CHARACTER SET utf8 NOT NULL,
`linkedin_link` varchar(1000) CHARACTER SET utf8 NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1905 DEFAULT CHARSET=latin1
以下是:
CREATE TABLE `education` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`uid` int(11) NOT NULL,
`institute_name` varchar(500) CHARACTER SET utf8 NOT NULL,
`exam_name` varchar(100) CHARACTER SET utf8 NOT NULL,
`major_group` varchar(100) CHARACTER SET utf8 NOT NULL,
`result` varchar(100) CHARACTER SET utf8 NOT NULL,
`passing_year` varchar(100) CHARACTER SET utf8 NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5279 DEFAULT CHARSET=latin1
这是job_apply表。请考虑db设计错误:
CREATE TABLE `job_apply` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`job_id` int(11) NOT NULL,
`applicant_uid` int(11) NOT NULL,
`ukey` varchar(50) NOT NULL,
`date` date NOT NULL,
`is_short_list` int(2) NOT NULL DEFAULT '0',
`is_rejected` int(2) NOT NULL DEFAULT '0',
`note` varchar(5000) CHARACTER SET utf8 NOT NULL,
`cv_viewed` int(11) NOT NULL DEFAULT '0',
`ssc_certificate` varchar(500) CHARACTER SET utf8 NOT NULL,
`ssc_marksheet` varchar(500) CHARACTER SET utf8 NOT NULL,
`hsc_certificate` varchar(500) CHARACTER SET utf8 NOT NULL,
`hsc_marksheet` varchar(500) CHARACTER SET utf8 NOT NULL,
`graduation_certificate` varchar(500) CHARACTER SET utf8 NOT NULL,
`graduation_marksheet` varchar(500) CHARACTER SET utf8 NOT NULL,
`experience_certificate` varchar(500) CHARACTER SET utf8 NOT NULL,
`recommendation_letter` varchar(500) CHARACTER SET utf8 NOT NULL,
`ans` varchar(5000) CHARACTER SET utf8 NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2079 DEFAULT CHARSET=latin1
答案 0 :(得分:0)
这里有几个问题,但有一个问题跳出了页面:你使用了像'%brac%'这样的通配符模式。请理解'brac%'可以利用索引,但带有百分号前导符号的通配符不能。你正在强迫桌面扫描。好几个,似乎。
你做了present_salary varchar(100),而不是数字,这似乎是一个非常糟糕的设计选择。如果你要求行BETWEEN '9000' and '11000'
会导致麻烦,因为词典顺序与数字顺序不同。
请修改您的问题以包含SHOW CREATE TABLE job_apply
的输出,还包括用户,简历,work_history,education和user_other_info。描述大概的表格大小,也许它们是数千行。最重要的是,确实包含EXPLAIN
输出,以便我们看到后端优化器确定的计划。
你在几个地方加入了uid,但是你选择不为优化器提供任何一个索引,所以它被迫进行表扫描。您没有包含EXPLAIN输出,但是从架构中很明显您无法利用选择性,并且必须扫描所有表。
感谢您添加格式,这非常有帮助。
错字:w.compnay_name
你有一堆latin1表,这很好,但你可能更愿意选择默认的utf8表。令人不安的是你混合使用latin1和utf8 varchars。更好地解决一个,例如UTF8。您严格加入整数uid,但如果您曾在文本列上使用equijoin,则需要使用相同的排序规则和相同的字符集才能正确利用索引。
答案 1 :(得分:0)
我称之为"爆炸内爆综合症"。查询JOINs
许多表,从而爆炸了正在查看的行数,然后它会使GROUP BY
崩溃。
通常的治疗方法是认为这是两个步骤。首先,找到与各种u.id
子句匹配的WHERE
值。由于您将数据分散在各个表中,因此这仍然很昂贵。但是,你不会在其他几十个专栏中走动,只是为了以后扔掉很多信息。
第二步是JOIN
(如果需要,再次,如果有必要)到各个表以获得所需的其他列。
建议您关注第1步的表现,因为第2步会很便宜(虽然详细)。
其他问题:
%
中的前导通配符(LIKE
)禁止使用索引。查看FULLTEXT
以查找由文本组成的列。LIKE
的数字(例如sex LIKE '%1%'
)。还有其他问题,但这些提示可能会帮助您前进。