Я обычно работаю с MSSQL, но из того, что я могу сказать, в вашем другом разделе, который дает вам хит.Вы нажимаете на таблицу 3 раза при каждом ее запуске, когда она может быть вдвое больше.
Это ваш исходный запрос, переформатированный для простого сравнения.
if(not exists( select CityID
from city
where CityName = SP_CityName)) then
insert into city( CityName, CitySynonyms, CityNumberPostOffice ,UpdatedDate)
values ( SP_CityName, CONCAT(',',SP_CitySynonyms, ','), SP_CityNumberPostOffice, SP_CityUpdatedDate);
else if((exists( select cityId
from city
where CityName = SP_CityName and
(UpdatedDate < SP_CityUpdatedDate or UpdatedDate = SP_CityUpdatedDate))) and
not exists( SELECT CitySynonyms
FROM city
WHERE CitySynonyms in ( select CitySynonyms
from city
where CitySynonyms like CONCAT('%,',SP_CitySynonyms,',%')))) then
update city set CitySynonyms = CONCAT(CitySynonyms,SP_CitySynonyms,','),
UpdatedDate = SP_CityUpdatedDate;
end if;
end if;
Это новый
if(not exists( select CityID
from city
where CityName = SP_CityName)) then
insert into city( CityName, CitySynonyms, CityNumberPostOffice ,UpdatedDate)
values ( SP_CityName, CONCAT(',',SP_CitySynonyms, ','), SP_CityNumberPostOffice, SP_CityUpdatedDate);
else if((exists( select cityId
from city
where CityName = SP_CityName and
UpdatedDate <= SP_CityUpdatedDate)) and
not exists( select CitySynonyms
from city
where CitySynonyms like CONCAT('%,',SP_CitySynonyms,',%'))) then
update city set CitySynonyms = CONCAT(CitySynonyms,SP_CitySynonyms,','),
UpdatedDate = SP_CityUpdatedDate;
end if;
end if;
Есть еще несколько вещей, которые можно сделать, чтобы ускорить запрос.Подобное предложение намного медленнее, чем равные.Если возможно, измените CitySynonyms, например, CONCAT ('%,', SP_CitySynonyms, ',%') на CitySynonyms = SP_CitySynonyms .Скажем, вы предоставляете синоним, начинающийся с «D», база данных может индексировать поиск прямо на D и даже не будет смотреть на другие записи.Конечно, чтобы это работало, вам понадобится индекс для таблицы, который включает столбец CitySynonyms.Если вы используете предложение Like, база данных будет запускать проверку instring () для столбца для каждой строки в таблице, что является основным ударом по производительности при работе с несколькими строками.
Думайте об этом с точки зрения телефонного справочника. Если я хочу человека с фамилией Смит, я бы посмотрел указатель в конце книги и обнаружил, что буква S начинается на странице 600 (называется поиском).Я не забочусь о первых 599 страницах и даже не смотрю на них.Без индекса мне пришлось бы просматривать каждую страницу, пока не добрались до имен, начинающихся с S, затем SM и т. Д. (Называемых сканированием).Но предложение LIKE похоже на поиск фамилии, содержащей SMITH, которая может быть любой из следующих (имя из Wiki) BlackSmith Coppersmith GoldSmith HammerSmith Smither Smithers и т. Д.Как видите, имена повсюду.Каждое имя нужно будет проверить, чтобы увидеть, содержит ли оно SMITH.Это одна из самых нехороших вещей, которую вы можете попросить кого-то сделать, но мы просим базу данных постоянно делать подобные вещи, а затем спрашиваем, почему это медленно.:)
Другая вещь - это (updatedDate , которую я изменил на updatedDate <= SP_CityUpdatedDate </strong>.Эта проверка действительно нужна?Потому что, если вы этого не сделаете, вы можете удалить весь этот раздел, если существует, потому что вы знаете, что он существует, если выполнение достигает этой точки в качестве самой первой проверки if, которая вернула false, поскольку существует запись.Так что теперь else if - это одно попадание в таблицу вместо трех.
if(not exists( Select CityID
from city
where CityName = SP_CityName)) then
insert into city( CityName, CitySynonyms, CityNumberPostOffice ,UpdatedDate)
values ( SP_CityName, CONCAT(',',SP_CitySynonyms, ','), SP_CityNumberPostOffice, SP_CityUpdatedDate);
else if(not exists( select CitySynonyms
from city
where CitySynonyms like CONCAT('%,',SP_CitySynonyms,',%'))) then
update city set CitySynonyms = CONCAT(CitySynonyms,SP_CitySynonyms,','),
UpdatedDate = SP_CityUpdatedDate;
end if;
end if;
EDIT - добавлено в ответ на вопросы в комментариях ниже.
Прежде чем идти дальше, следует
update city set CitySynonyms = CONCAT(CitySynonyms,SP_CitySynonyms,','),
UpdatedDate = SP_CityUpdatedDate;
be
update city set CitySynonyms = CONCAT(CitySynonyms,SP_CitySynonyms,','),
UpdatedDate = SP_CityUpdatedDate
where CityName = SP_CityName;
Потому что, как и в настоящее время, он добавляет синоним к каждой строке в базе данных, когда я думаю, что он должен обновлять только ту, которая вас интересует.
Что касается аналогичного утверждения.Я думаю, что только что понял, что происходит.Поправьте меня если я ошибаюсь.Столбец CitySynonyms - это большое текстовое поле в вашей таблице, в котором несколько значений разделены запятыми, и вы пытаетесь найти совпадение в этой строке с помощью оператора like.
Если это так, можно линемного изменить структуру таблицы?Это означает перемещение столбца CitySynonyms во вторую таблицу.
CREATE TABLE city ( CityID int(20) NOT NULL AUTO_INCREMENT,
CityName varchar(100) NOT NULL,
CityNumberPostOffice varchar(100) DEFAULT NULL,
UpdatedDate date DEFAULT NULL,
PRIMARY KEY (CityID) ) ENGINE=InnoDB DEFAULT CHARSET=utf8
CREATE TABLE CitySynonym ( CitySynonymID int(20) NOT NULL AUTO_INCREMENT,
CityID int(20) NOT NULL ,
CitySynonym varchar(100) NOT NULL,
PRIMARY KEY (CitySynonymID) ) ENGINE=InnoDB DEFAULT CHARSET=utf8
Для каждого города можно использовать несколько синонимов.Его становится намного проще в использовании и обслуживании, не говоря уже о том, что предложение LIKE больше не потребуется.
Example:
City Table
CityID CityName
1 Brisbane
2 Syndney
City Synonym Table
CitySynoymnID CityID Synonym
1 1 BNE
2 1 BRISSY
3 2 SYD