refactor: using indexed temporary table as array works speed wonders :)

This commit is contained in:
Martin Ambrus
2017-10-27 21:04:16 +02:00
parent 0d84b5f3b4
commit 5a967055f4
3 changed files with 53 additions and 168 deletions
+3 -3
View File
@@ -908,13 +908,13 @@ class MYSQLi_DB implements IDbConnection {
global $autoprefix; global $autoprefix;
if (is_array($wid)) { if (is_array($wid)) {
$wid = '"'.implode(',', $wid).'"'; $wid = '(' . implode('),(', $wid) . ')';
} else { } else {
$wid = (int) $wid; $wid = '(' . (int) $wid . ')';
} }
// load the oasis regeneration (in-game) and units generation (during install) SQL file // load the oasis regeneration (in-game) and units generation (during install) SQL file
// and replace village ID for the given $wid // and replace village IDs for the given $wid
$str = file_get_contents($autoprefix."var/db/datagen-oasis-troops-regen.sql"); $str = file_get_contents($autoprefix."var/db/datagen-oasis-troops-regen.sql");
$str = preg_replace(["'%PREFIX%'", "'%VILLAGEID%'", "'%NATURE_REG_TIME%'"], [TB_PREFIX, $wid, ($automation ? NATURE_REGTIME : -1)], $str); $str = preg_replace(["'%PREFIX%'", "'%VILLAGEID%'", "'%NATURE_REG_TIME%'"], [TB_PREFIX, $wid, ($automation ? NATURE_REGTIME : -1)], $str);
$result = $this->dblink->multi_query($str); $result = $this->dblink->multi_query($str);
+47 -165
View File
@@ -16,15 +16,29 @@ SET @natureRegTime = %NATURE_REG_TIME%;
-- Oasis village ID. -- A temporary table with oasis village ID(s).
-- -- Used instead of variable so we can work with it as with array.
-- type: int -- The only other option would be to repeat IDs replacements below
-- description: when > -1, used to regenerate units of a single oasis (when conquered > unoccupied) -- or define them once in a string and use FIND_IN_SET() for lookups,
-- when == -1, installation or server reset in progress, all oasis data are updated -- which is TERRIBLE, performance-wise (since it doesn't use indexes).
SET @village = %VILLAGEID%; CREATE TEMPORARY TABLE %PREFIX%oids (id INT NOT NULL, PRIMARY KEY (id));
INSERT INTO %PREFIX%oids VALUES %VILLAGEID%;
-- Equivalent to "VILLAGEID === -1" (in PHP). Determines whether we have
-- any single oasis to actually update (mode = conquered > unocupied)
-- or we're updating 1 or more specific oasis (mode = install, server reset, Automation's nature regen).
SET @noVillage = ((SELECT id FROM %PREFIX%oids LIMIT 1) = -1);
-- faster access to first oasis ID, so we don't need to reselect all the time below
SET @firstVillage = (SELECT id FROM %PREFIX%oids LIMIT 1);
-- minimum and maximum number of units for oasis with "high" field set to 0 -- minimum and maximum number of units for oasis with "high" field set to 0
SET @minUnitsForOasis0 = 15; SET @minUnitsForOasis0 = 15;
SET @maxUnitsForOasis0 = 30; SET @maxUnitsForOasis0 = 30;
@@ -59,19 +73,7 @@ UPDATE %PREFIX%odata
WHERE WHERE
@natureRegTime = -1 @natureRegTime = -1
AND AND
( conqured = @firstVillage;
(
-- should we have a list of IDs, we need to use FIND_IN_SET
LOCATE(",", @village) > 0
AND
FIND_IN_SET(conqured, @village)
)
OR
(
-- for a single ID, we use a simple condition which can definitely use an index as well
conqured = @village
)
);
-- --------------------------------------------- -- ---------------------------------------------
-- remove past reports (conquered > unoccupied) -- remove past reports (conquered > unoccupied)
@@ -80,19 +82,7 @@ DELETE FROM %PREFIX%ndata
WHERE WHERE
@natureRegTime = -1 @natureRegTime = -1
AND AND
( toWref = @firstVillage;
(
-- should we have a list of IDs, we need to use FIND_IN_SET
LOCATE(",", @village) > 0
AND
FIND_IN_SET(toWref, @village)
)
OR
(
-- for a single ID, we use a simple condition which can definitely use an index as well
toWref = @village
)
);
-- ---------------------------------------------------------------- -- ----------------------------------------------------------------
@@ -105,19 +95,7 @@ SET
WHERE WHERE
@natureRegTime > -1 @natureRegTime > -1
AND AND
( wref IN ( SELECT id FROM %PREFIX%oids );
(
-- should we have a list of IDs, we need to use FIND_IN_SET
LOCATE(",", @village) > 0
AND
FIND_IN_SET(wref, @village)
)
OR
(
-- for a single ID, we use a simple condition which can definitely use an index as well
wref = @village
)
);
-- ----------------------------------------------------------------------- -- -----------------------------------------------------------------------
@@ -137,7 +115,7 @@ UPDATE %PREFIX%units u
WHERE WHERE
( (
( (
@village = -1 @firstVillage = -1
AND AND
vref IN( vref IN(
SELECT SELECT
@@ -150,21 +128,9 @@ UPDATE %PREFIX%units u
) )
OR OR
( (
@village > -1 @firstVillage = -1 > -1
AND AND
( vref IN ( SELECT id FROM %PREFIX%oids )
(
-- should we have a list of IDs, we need to use FIND_IN_SET
LOCATE(",", @village) > 0
AND
FIND_IN_SET(vref, @village)
)
OR
(
-- for a single ID, we use a simple condition which can definitely use an index as well
vref = @village
)
)
) )
) )
AND AND
@@ -205,7 +171,7 @@ UPDATE %PREFIX%units u
WHERE WHERE
( (
( (
@village = -1 @firstVillage = -1 = -1
AND AND
vref IN( vref IN(
SELECT SELECT
@@ -218,21 +184,9 @@ UPDATE %PREFIX%units u
) )
OR OR
( (
@village > -1 @firstVillage = -1 > -1
AND AND
( vref IN ( SELECT id FROM %PREFIX%oids )
(
-- should we have a list of IDs, we need to use FIND_IN_SET
LOCATE(",", @village) > 0
AND
FIND_IN_SET(vref, @village)
)
OR
(
-- for a single ID, we use a simple condition which can definitely use an index as well
vref = @village
)
)
) )
) )
AND AND
@@ -271,7 +225,7 @@ UPDATE %PREFIX%units u
WHERE WHERE
( (
( (
@village = -1 @firstVillage = -1 = -1
AND AND
vref IN( vref IN(
SELECT SELECT
@@ -284,21 +238,9 @@ UPDATE %PREFIX%units u
) )
OR OR
( (
@village > -1 @firstVillage = -1 > -1
AND AND
( vref IN ( SELECT id FROM %PREFIX%oids )
(
-- should we have a list of IDs, we need to use FIND_IN_SET
LOCATE(",", @village) > 0
AND
FIND_IN_SET(vref, @village)
)
OR
(
-- for a single ID, we use a simple condition which can definitely use an index as well
vref = @village
)
)
) )
) )
AND u31 <= ( AND u31 <= (
@@ -335,7 +277,7 @@ UPDATE %PREFIX%units u
WHERE WHERE
( (
( (
@village = -1 @firstVillage = -1 = -1
AND AND
vref IN( vref IN(
SELECT SELECT
@@ -348,21 +290,9 @@ UPDATE %PREFIX%units u
) )
OR OR
( (
@village > -1 @firstVillage = -1 > -1
AND AND
( vref IN ( SELECT id FROM %PREFIX%oids )
(
-- should we have a list of IDs, we need to use FIND_IN_SET
LOCATE(",", @village) > 0
AND
FIND_IN_SET(vref, @village)
)
OR
(
-- for a single ID, we use a simple condition which can definitely use an index as well
vref = @village
)
)
) )
) )
AND u31 <= ( AND u31 <= (
@@ -398,7 +328,7 @@ UPDATE %PREFIX%units u
WHERE WHERE
( (
( (
@village = -1 @firstVillage = -1 = -1
AND AND
vref IN( vref IN(
SELECT SELECT
@@ -411,21 +341,9 @@ UPDATE %PREFIX%units u
) )
OR OR
( (
@village > -1 @firstVillage = -1 > -1
AND AND
( vref IN ( SELECT id FROM %PREFIX%oids )
(
-- should we have a list of IDs, we need to use FIND_IN_SET
LOCATE(",", @village) > 0
AND
FIND_IN_SET(vref, @village)
)
OR
(
-- for a single ID, we use a simple condition which can definitely use an index as well
vref = @village
)
)
) )
) )
AND u31 <= ( AND u31 <= (
@@ -462,7 +380,7 @@ UPDATE %PREFIX%units u
WHERE WHERE
( (
( (
@village = -1 @firstVillage = -1 = -1
AND AND
vref IN( vref IN(
SELECT SELECT
@@ -475,21 +393,9 @@ UPDATE %PREFIX%units u
) )
OR OR
( (
@village > -1 @firstVillage = -1 > -1
AND AND
( vref IN ( SELECT id FROM %PREFIX%oids )
(
-- should we have a list of IDs, we need to use FIND_IN_SET
LOCATE(",", @village) > 0
AND
FIND_IN_SET(vref, @village)
)
OR
(
-- for a single ID, we use a simple condition which can definitely use an index as well
vref = @village
)
)
) )
) )
AND u31 <= ( AND u31 <= (
@@ -527,7 +433,7 @@ UPDATE %PREFIX%units u
WHERE WHERE
( (
( (
@village = -1 @firstVillage = -1 = -1
AND AND
vref IN( vref IN(
SELECT SELECT
@@ -540,21 +446,9 @@ UPDATE %PREFIX%units u
) )
OR OR
( (
@village > -1 @firstVillage = -1 > -1
AND AND
( vref IN ( SELECT id FROM %PREFIX%oids )
(
-- should we have a list of IDs, we need to use FIND_IN_SET
LOCATE(",", @village) > 0
AND
FIND_IN_SET(vref, @village)
)
OR
(
-- for a single ID, we use a simple condition which can definitely use an index as well
vref = @village
)
)
) )
) )
AND u31 <= ( AND u31 <= (
@@ -600,7 +494,7 @@ UPDATE %PREFIX%units u
WHERE WHERE
( (
( (
@village = -1 @firstVillage = -1 = -1
AND AND
vref IN( vref IN(
SELECT SELECT
@@ -613,21 +507,9 @@ UPDATE %PREFIX%units u
) )
OR OR
( (
@village > -1 @firstVillage = -1 > -1
AND AND
( vref IN ( SELECT id FROM %PREFIX%oids )
(
-- should we have a list of IDs, we need to use FIND_IN_SET
LOCATE(",", @village) > 0
AND
FIND_IN_SET(vref, @village)
)
OR
(
-- for a single ID, we use a simple condition which can definitely use an index as well
vref = @village
)
)
) )
) )
AND u31 <= ( AND u31 <= (
+3
View File
@@ -96,6 +96,8 @@ INSERT INTO %PREFIX%wdata
WHERE @row2 <= (%WORLDSIZE% - 1)) as y WHERE @row2 <= (%WORLDSIZE% - 1)) as y
) as generator; ) as generator;
-- populate oasis data -- populate oasis data
INSERT INTO %PREFIX%odata INSERT INTO %PREFIX%odata
SELECT SELECT
@@ -138,6 +140,7 @@ INSERT INTO %PREFIX%odata
oasistype <> 0; oasistype <> 0;
-- create some defensive units for existing oasis -- create some defensive units for existing oasis
INSERT INTO %PREFIX%units (vref) INSERT INTO %PREFIX%units (vref)
SELECT SELECT