我需要查询或重新设计我的数据库的帮助。我不是数据库管理员,也不是MySQL wiz。
我有以下表格:
CREATE TABLE IF NOT EXISTS `pop_contor` (
`key` varchar(50) NOT NULL,
`uniqueHandler` varchar(30) DEFAULT NULL,
`uniqueLink` varchar(30) DEFAULT NULL,
`uniqueUser` varchar(30) DEFAULT NULL,
`owner` varchar(50) NOT NULL,
`ip` varchar(15) DEFAULT NULL,
`page` varchar(500) DEFAULT NULL,
`share` float DEFAULT NULL,
`cadv` float NOT NULL,
`os` varchar(50) NOT NULL,
`browsershort` varchar(50) NOT NULL,
`browser` varchar(50) DEFAULT NULL,
`country` varchar(10) DEFAULT NULL,
`date` date DEFAULT NULL,
`hour` int(2) NOT NULL,
`tstamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`key`),
KEY `contor_IX1` (`uniqueLink`,`ip`),
KEY `owner` (`owner`,`share`,`hour`),
KEY `uniqueUser` (`uniqueUser`,`share`,`hour`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
和
CREATE TABLE IF NOT EXISTS `pop_links` (
`unique` varchar(8) NOT NULL DEFAULT '',
`uniqueUser` varchar(30) DEFAULT NULL,
`uniqueCategories` varchar(150) DEFAULT NULL,
`browser` varchar(60) NOT NULL,
`os` varchar(50) NOT NULL,
`country` varchar(100) NOT NULL,
`name` varchar(50) DEFAULT NULL,
`url` varchar(500) CHARACTER SET ascii DEFAULT NULL,
`description` varchar(150) DEFAULT NULL,
`bid` varchar(6) DEFAULT NULL,
`amount` varchar(5) DEFAULT NULL,
`remain` varchar(20) DEFAULT NULL,
`rtoday` varchar(20) NOT NULL DEFAULT '0',
`frequency` varchar(2) DEFAULT NULL,
`dlimit` varchar(6) NOT NULL DEFAULT '0',
`hours` varchar(100) NOT NULL DEFAULT 'all',
`block` varchar(500) CHARACTER SET ascii NOT NULL,
`valid` int(1) DEFAULT NULL,
`payed` int(1) DEFAULT NULL,
`startDate` date DEFAULT NULL,
`endDate` date DEFAULT NULL,
`date` date DEFAULT NULL,
PRIMARY KEY (`unique`),
KEY `unique` (`unique`,`uniqueCategories`,`browser`,`os`,`country`,`url`,`bid`,`remain`,`rtoday`,`frequency`,`hours`,`block`,`valid`,`startDate`,`endDate`,`uniqueUser` )
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
我要做的是根据几个标准向每个访问者(基于IP)显示最合适的链接。我已经尝试了几个查询,但由于服务器仍然过载而失败。当pop_contor表获得大约200,000个条目时,它主要是hapens。表链接中有大约30行。
第一次尝试是做一个选择>其中>选择>其中>选择>其中我吃了午餐,包括我的午餐盒。
第二次尝试是(查询花了大约5秒钟完成):
SELECT l. * FROM pop_links AS l
LEFT JOIN ( SELECT uniqueLink, SUM( ip = '".$ip."' ) AS ip_visits
FROM pop_contor
GROUP BY uniqueLink ) AS c
ON c.uniqueLink = l.unique AND ip_visits <= frequency
WHERE (`uniqueCategories` LIKE '%,".$cat.",%'OR `uniqueCategories` = '1')
AND (`hours` LIKE '%,".date("H").",%' OR `hours` = 'all')
AND (`browser` LIKE '%".$user_browser[name]."%' OR `browser` = '1')
AND (`country` LIKE '%".$ccode."%' OR `country` = '1')
AND (`os` LIKE '%".$user_browser[platform]."%' OR `os` = '1')
AND (`remain` > '0')
AND (`rtoday` > '0')
AND `valid` = '1'
AND (`block` NOT LIKE '%".$unique."%')
ORDER BY `bid` DESC, `remain` DESC
LIMIT 1
说明:
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY l ALL NULL NULL NULL NULL 16 Using where; Using temporary; Using filesort
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 16
2 DERIVED pop_contor index NULL contor_IX1 141 NULL 299128 Using index
第三次尝试:
SELECT pop_links.unique, pop_links.uniqueUser, pop_links.uniqueCategories, pop_links.browser, pop_links.os, pop_links.country, pop_links.url, pop_links.bid, pop_links.remain, pop_links.rtoday, pop_links.frequency, pop_links.hours, pop_links.block, pop_links.valid, pop_links.startDate, pop_links.endDate, COUNT( IF( pop_contor.ip = '".$ip."', 1, NULL ) ) < pop_links.frequency AS toto
FROM pop_links
LEFT JOIN pop_contor
ON pop_links.unique = pop_contor.uniqueLink
WHERE (`uniqueCategories` LIKE '%,".$cat.",%' OR `uniqueCategories` = '1')
AND (`hours` LIKE '%,".date("H").",%' OR `hours` = 'all')
AND (pop_links.browser LIKE '%".$user_browser[name]."%' OR pop_links.browser = '1')
AND (pop_links.country LIKE '%".$ccode."%' OR pop_links.country = '1')
AND (pop_links.os LIKE '%".$user_browser[platform]."%' OR pop_links.os = '1')
AND (`remain` > '0')
AND `rtoday` > '0'
AND `valid` = '1'
AND (`block` NOT LIKE '%".$unique."%')
GROUP BY pop_links.unique, pop_contor.uniqueLink
ORDER BY `toto` DESC , pop_links.bid DESC , pop_links.remain DESC
LIMIT 1
说明:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE pop_links index NULL unique 2683 NULL 16 Using where; Using index; Using temporary; Using f...
1 SIMPLE pop_contor ref contor_IX1 contor_IX1 93 admin_pops.pop_links.unique 13277 Using index
查询在大约0.3秒内完成,但服务器上的负载仍然很高。 SHOW PROCESSLIST
向我展示了很多“复制到tmp表”的状态。
答案 0 :(得分:0)
代替
hours LIKE '%,".date("H").",%' OR hours = 'all'
同
paused = 0
(添加了一个暂停链接的列)。
负载从~4降至~0.20。我无法相信column LIKE %something
可能对查询效果产生多大影响。