views:

39

answers:

1

Hi, I was wondering if it was possible to speed up this MySQL query. Currently, I am calling it 20,000+ times, and it takes a while to run (a while being about 10 to 20 minutes).

Here is the basic table layout:

db1:
INT(11) id
VARCHAR(45) col1
VARCHAR(100) col2
VARCHAR(100) col3

db2:
VARCHAR(45) id

db3:
VARCHAR(45) fk_db2
INT(11) fk_db1

Here is the stored routine:

DELIMITER $$

CREATE DEFINER=`root`@`localhost` PROCEDURE `proc`(IN fk VARCHAR(45),
                                            IN a VARCHAR(45),
                                            IN b VARCHAR(100),
                                            IN c VARCHAR(65))
BEGIN
    SET @id=0;
    SELECT id INTO @id FROM db1 WHERE db1.col1=a
                                AND db1.col2=b
                                AND db1.col3=c;
    IF @id=0 THEN
        INSERT INTO db1 (col1, col2, col3)
            VALUES (a, b, c);
        SELECT LAST_INSERT_ID() INTO @id;
    END IF;

    -- Association table for db2 and db1.
    INSERT IGNORE INTO db3 (fk_db1, fk_db2) 
        VALUES(@id, fk);
END

The main point of this routine, is I want to get the ID of a specific record, or create one if it doesn't exist. Then I want to associate the fk passed in and the ID that I just found out. I'm sure there is a MySQL one-liner for this, but I have been unable to figure it out.

Any help is greatly appreciated!!

Thank you!

By the way, the names of columns are much better in the actual database, but I can't share the names with you all.

+2  A: 

Actually, unless I'm missing something, that doesn't look all that slow. Can you define "a while" in "takes a while"?

Do you have an index on col1/col2/col3?

How exactly are you calling the procedure in your application? You are reusing the database connections, right?

Can you bundle multiple calls into a single transaction if you're not already?

Nicholas Knight
A while is about 10 - 20 minutes (long enough for me to write the question and do a lot of searching the internet to figure out an answer).I do not have an index on col1, col2, or col3.In my application, I have one database connection and I am executing the statements in a batch.
KLee1
@KLee1: Well, there's your problem. You're doing a SELECT on a table without indexes on the appropriate columns. That will make things incredibly slow. Add indexes.
Nicholas Knight
You should time that first select, and view the query plan for it, likely you could benefit from adding indexes to the db1 table.
nos
Thank you for the suggestions everyone (+1s around) I have to admit that I'm not very familiar with indexes, as I learned MySQL about 7 days ago. I'll read up on them and try them when I get to work tomorrow.
KLee1
Thanks guys! Indexes helped the speed a lot. Now only takes about a minute.
KLee1