我一直在使用以下查询搜索一些数据。我是新手。如果有任何设计错误,请原谅。
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 表。请考虑数据库设计错误:
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
最佳答案
这里有几个问题,但有一个问题很明显:您使用了“%brac%”等通配符模式。请理解,“brac%”可以利用索引,但带有前导百分号的通配符则不能。您正在强制进行表扫描。似乎有几个。
您制作了present_salary varchar(100),而不是数字,这似乎是一个极其糟糕的设计选择。如果您请求 '9000' 和 '11000' 之间的行
,则会导致麻烦,因为字典顺序与数字顺序不同。
请编辑您的问题以包含 SHOW CREATE TABLE job_apply
的输出,以及用户、简历、work_history、教育和 user_other_info。描述大概的表大小,也许有几千行。最重要的是,一定要包括 EXPLAIN
输出,以便我们看到后端优化器确定的计划。
您在多个位置加入了 uid,但您选择不向优化器提供其中任何一个的索引,因此它被迫进行表扫描。您没有包含 EXPLAIN 输出,但从架构中可以清楚地看出您无法利用选择性,并且必须扫描所有表。
感谢您添加的格式,这非常有帮助。
拼写错误:w.compnay_name
您有一堆 latin1 表,这很好,但您可能更愿意选择默认的 utf8 表。令人不安的是你混合使用 latin1 和 utf8 varchars。最好选择一个,例如utf8。您严格按照整数 uid 进行联接,但如果您要对文本列进行等联接,则需要相同的排序规则和相同的字符集才能正确利用索引。
关于MySQL GROUP BY 函数需要很多时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47114556/