I have trouble with indexing this query :
SELECT *,
(ROUND(SQRT(
POW(LEAST(ABS(-12 - wdata.x),
ABS(401 - ABS(-12 - wdata.x))), 2) +
POW(LEAST(ABS(45 - wdata.y),
ABS(401 - ABS(45 - wdata.y))), 2)),3)
) AS distance
FROM odata
LEFT JOIN wdata ON wdata.id=odata.vref
WHERE TRUE
HAVING distance<4.9497474683058326708059105347339
ORDER BY distance
LIMIT 30
and the result is :
+----+-------------+-------+--------+---------------+---------+---------+-----------------------------+-------+---------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+--------+---------------+---------+---------+-----------------------------+-------+---------------------------------+ | 1 | SIMPLE | odata | ALL | NULL | NULL | NULL | NULL | 19118 | Using temporary; Using filesort | | 1 | SIMPLE | wdata | eq_ref | PRIMARY | PRIMARY | 4 | mytravia_1000-14.odata.vref | 1 | NULL | +----+-------------+-------+--------+---------------+---------+---------+-----------------------------+-------+---------------------------------+ 2 rows in set (0.00 sec)
i know it shows 0.00 sec is execution time but this query will run many many times and it shows its will slow my database i dont know why !
every time i see row examined is 459448 for this query so its quite bad for my work in some reasons .
can anyone give a suggestion ? how can i make a proper index for odata table? or can i use sub querys to fix it ?
the tables are :
explain odata:
vref int(10) unsigned NO PRI NULL type tinyint(4) NO NULL conqured mediumint(8) unsigned NO NULL wood float(12,2) NO NULL iron float(12,2) NO NULL clay float(12,2) NO NULL woodp float(12,2) NO NULL ironp float(12,2) NO NULL clayp float(12,2) NO NULL maxstore mediumint(8) unsigned NO NULL crop float(12,2) NO NULL cropp float(12,2) NO NULL maxcrop mediumint(8) unsigned NO NULL lasttrain int(10) unsigned NO NULL lastfarmed int(10) unsigned NO NULL lastupdated int(10) unsigned NO NULL loyalty tinyint(4) NO 100 owner smallint(5) unsigned NO 2 name char(45) NO Oasis
and explain wdata:
id int(10) unsigned NO PRI NULL auto_increment fieldtype tinyint(3) NO NULL oasistype tinyint(3) NO NULL x smallint(5) NO MUL NULL y smallint(5) NO MUL NULL occupied tinyint(4) NO NULL image char(12) NO MUL NULL pos tinyint(3) NO MUL NULL
i have to say wdata.id and odata.vref is indexed already !
tables structure ->
CREATE TABLE IF NOT EXISTS `odata` ( `vref` int(10) unsigned NOT NULL, `type` tinyint(4) NOT NULL, `conqured` mediumint(8) unsigned NOT NULL, `wood` float(12,2) NOT NULL, `iron` float(12,2) NOT NULL, `clay` float(12,2) NOT NULL, `woodp` float(12,2) NOT NULL, `ironp` float(12,2) NOT NULL, `clayp` float(12,2) NOT NULL, `maxstore` mediumint(8) unsigned NOT NULL, `crop` float(12,2) NOT NULL, `cropp` float(12,2) NOT NULL, `maxcrop` mediumint(8) unsigned NOT NULL, `lasttrain` int(10) unsigned NOT NULL, `lastfarmed` int(10) unsigned NOT NULL, `lastupdated` int(10) unsigned NOT NULL, `loyalty` tinyint(4) NOT NULL DEFAULT '100', `owner` smallint(5) unsigned NOT NULL DEFAULT '2', `name` char(45) NOT NULL DEFAULT 'Unoccupied Oasis', PRIMARY KEY (`vref`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
And for wdata is ->
CREATE TABLE IF NOT EXISTS `wdata` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `fieldtype` tinyint(3) NOT NULL, `oasistype` tinyint(3) NOT NULL, `x` smallint(5) NOT NULL, `y` smallint(5) NOT NULL, `occupied` tinyint(4) NOT NULL, `image` char(12) NOT NULL, `pos` tinyint(3) NOT NULL, PRIMARY KEY (`id`), KEY `x` (`x`), KEY `y` (`y`), KEY `image` (`image`), KEY `pos` (`pos`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=160802 ;
best regards.