问题
I'm writing a stored procedure for a Sybase database. I'm using Sybase Central 16.0 as my development environment. The machine I'm using runs Microsoft Windows Server 2012 R2 Standard and has 16GB RAM running on a 2.8GHz CPU.
My stored procedure uses a cursor to iterate over the records in a table with about 400,000 reecords. Each record is written incrementally into a LONG VARCHAR
variable and every Nth record the proc will run an MD5 hash value on the variable and store the value in a separate table.
TABLE_NAME, DATE_TIME_RAN, FROM_RECORD, TO_RECORD, HASH_VALUE
If I run only the stored procedure to hash this table as a SQL block in SQL Anywhere (e.g.: BEGIN ... <hash the table here> ... END;
) it goes through all records and completes successfully in about two minutes. However if I run this stored procedure as an embedded command in another stored procedure (e.g.: CALL <MY_SCHEMA>.<MY_STORED_PROCEDURE>
) then it never completes.
Why would running the stored procedure (on the same dataset) from within another stored procedure perform differently?
回答1:
Managed to find a much better solution to the issue without trawling through the table. I thought I'd post the solution here for anyone who might face a similar issue.
The requirement for the stored procedure was to loop through a large table one row at a time, concatenating the contents of every column in the row into a string and assigning this to a variable. Every N rows this variable's value would be written to a separate table. Previously I had been using a cursor to do this but a developer on our team discovered a much faster way using the WITH clause.
INSERT INTO <MY_SCHEMA>.<MY_TABLE_THAT_WILL_CONTAIN_THE_CONCATENATED_VALUES_OF_EVERY_N_ROWS>
WITH
CONCATENATE_ROWS AS (
SELECT RANK() OVER (ORDER BY <PRIMARY_KEY_COLUMN>) AS ROWID, <PRIMARY_KEY_COLUMN>, <COLUMN_1> || '' || <COLUMN_2> || '' || ... <COLUMN_N> AS ROW_DETAIL
FROM <MY_TABLE_THAT_I_AM_QUERYING>
ORDER BY <PRIMARY_KEY_COLUMN>
),
GROUPED_ROWS AS (
SELECT (((CONCATENATE_ROWS.ROWID-1)/ <number of rows I want to concatenate, e.g.: 10>)+1) AS GROUPID, CAST(LIST(CONCATENATE_ROWS.ROW_DETAIL, '' ORDER BY <PRIMARY_KEY_COLUMN>) AS VARCHAR(4000)) AS CONCAT_DETAILS
FROM CONCATENATE_ROWS
GROUP BY (((CONCAT_ORDERS.ROWID-1)/ <number of rows I want to concatenate, e.g.: 10>)+1)
)
SELECT <Whatever columns I want to insert into <MY_TABLE_THAT_WILL_CONTAIN_THE_CONCATENATED_VALUES_OF_EVERY_N_ROWS>>
FROM GROUPED_ROWS;
来源:https://stackoverflow.com/questions/54215723/sybase-stored-procedure-called-from-within-another-stored-procedure-is-too-slow