MySql - 性能问题可能是由动态 SQL 引起的吗?

标签 mysql performance stored-procedures database-performance

我们有这个 MySQL SP,它使用动态 SQL。 看起来它在负载下表现不佳。

该 SP 在负载下可能会变慢,因为它使用动态 SQL? 动态 SQL 会导致 MySql 中的性能问题(例如,因为它没有被引擎缓存)吗?

请注意,此 SP 是从其他几个 SP 调用的。它使用临时表将结果传递给父 SP。

CREATE PROCEDURE `CreateAreas`(
    _areas varchar(21844),
    _comparisonGroup varchar(21844),
    _parentArea varchar(21844),
    _areaType varchar(21844)
)
BEGIN

    -- create temporary table "areas"
    -- fill with area ids

    create temporary table areas (
        id int not null,
        code varchar(30),
        name varchar(100),
        shortName varchar(100),
        levelid int not null,
        sortOrder int not null,
        key (id)
    );

    -- assumes that only one of the 3 options is valid, areas, comparison group, bounded comparison group

    if (_areas is not null) then

        set @sql = concat('insert into areas (id, code, name, shortName, levelid, sortOrder) select id, Code, Name, ShortName, LevelID, 0 from GeoArea where Code in (''', replace(_areas, ',', ''','''), ''')');
        prepare stmt from @sql;
        execute stmt;
        deallocate prepare stmt;

    elseif (_comparisonGroup is not null) then

        -- might not be the most efficient way, but is consistent with the approach above, and we do not expect the list to be long
        insert into areas (id, code, name, shortName, levelid, sortOrder)
        select GeoAreaID, GeoArea.Code, GeoArea.Name, GeoArea.ShortName, GeoArea.LevelID, SortOrder
        from ComparisonGroupGeoAreaLink
        INNER JOIN
        GeoArea
        ON GeoArea.ID = GeoAreaID
        where ComparisonGroupID = (select id from ComparisonGroup where Identifier = _comparisonGroup)
        and IsMember = 1;

    elseif (_parentArea is not null and _areaType is not null) then

        -- might not be the most efficient way, but is consistent with the approach above, and we do not expect the list to be long
        insert into areas (id, code, name, shortName, levelid, sortOrder)
    select a.ID, a.Code, a.Name, a.ShortName, a.LevelID, 0
        from (select id from GeoArea where Code = _parentArea) as t
        INNER JOIN
        GeoAreaLinkCache c
        ON
        c.ParentAreaID = t.id
        inner join GeoArea a
        on c.ChildAreaID = a.ID
        INNER JOIN
        (select id from GeoAreaLevel where Identifier = _areaType) as l
        ON
        a.LevelID = l.id;        

    elseif (_areaType is not null) then

        -- might not be the most efficient way, but is consistent with the approach above, and we do not expect the list to be long
        set @sql = concat('insert into areas (id, code, name, shortName, levelid, sortOrder)
        select a.ID, a.Code, a.Name, a.ShortName, a.LevelID, 0
        from 
        (select id from GeoAreaLevel where Identifier in (''', replace(_areaType, ',', ''','''), ''')) l
        INNER JOIN
        GeoArea a
        ON
        a.LevelID = l.id');
        prepare stmt from @sql;
        execute stmt;
        deallocate prepare stmt;


    end if;                 

END

最佳答案

是的。存储过程的优点是可以解析它们、可以缓存查询计划等。

动态 SQL(或即席查询)没有这样的优势。

也就是说,您的性能瓶颈不太可能来自动态 SQL,而更有可能来自缺乏索引、过多插入/删除等。

关于MySql - 性能问题可能是由动态 SQL 引起的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19807451/

相关文章:

PHP重定向404到mysql数据库中最近的url

php - CakePHP 数据库连接 "Mysql"丢失,或无法创建

java - Java 数组更高效

mysql - 以变​​量为参数的 SQL 更新

sql-server - SQL Server 中带有条件 Where 子句的存储过程

sql - 直接执行语句和从存储过程执行语句时的执行计划不同

php - laravel5.1 使用 eloquent 检索不直接相关的属性

php - Facebook 登录最佳实践

ios - 计算 ALAssetLibrary 的最快方法?

javascript - 谁能解释这种意外的 V8 JavaScript 性能行为?