2

I have following procedure:

CREATE PROCEDURE getProjectTeams(IN p_idProject INTEGER)
BEGIN
 SELECT idTeam, name, workersCount, confirmersCount, isConfirm 
 FROM Teams JOIN team_project USING (idTeam)
 WHERE idProject = p_idProject;
END $$

And here are CREATE TABLE script for tables Teams and team_project:

CREATE TABLE Teams (
 idTeam INT PRIMARY KEY auto_increment,
 name CHAR(20) NOT NULL UNIQUE,
 isConfirm BOOL DEFAULT 0,
 workersCount SMALLINT DEFAULT 0,
 confirmersCount SMALLINT DEFAULT 0 
) engine = innodb DEFAULT CHARACTER SET=utf8 COLLATE=utf8_polish_ci;

CREATE TABLE team_project (
idTeam INT NOT NULL,
idProject INT NOT NULL,
FOREIGN KEY(idTeam) REFERENCES Teams(idTeam)
    ON DELETE CASCADE
    ON UPDATE CASCADE,
FOREIGN KEY (idProject) REFERENCES Projects(idProject)
    ON DELETE CASCADE
    ON UPDATE CASCADE,
PRIMARY KEY(idTeam, idProject)
) engine = innodb DEFAULT CHARACTER SET=utf8 COLLATE=utf8_polish_ci;

I have few databases with identical schema on the server, but this procedure is being logged only if it is called by one database. Calles done by those othere databases are not being logged. It's not a question of being slow or not slow query (it always takes about 0.0001s). It's about why it is logged as not using indexes. How is that possible?

As Zagor23 suggested I run that EXPLAIN an and here are the results. a) in database where procedure is logged:

| id | select_type | table        | type | possible_keys     | key       | key_len | ref   | rows | Extra                          |
|  1 | SIMPLE      | team_project | ref  | PRIMARY,idProject | idProject | 4       | const |    3 | Using index                    |
|  1 | SIMPLE      | Teams        | ALL  | PRIMARY           | NULL      | NULL    | NULL  |    4 | Using where; Using join buffer |

b) database, where procedure is not logged:

| id | select_type | table        | type   | possible_keys     | key       | key_len | ref                              | rows | Extra       |
|  1 | SIMPLE      | team_project | ref    | PRIMARY,idProject | idProject | 4       | const                            |    1 | Using index |
|  1 | SIMPLE      | Teams        | eq_ref | PRIMARY           | PRIMARY   | 4       | ecovbase.team_project.idTeam |    1 |             |

The fact is - the data are a bit different, but not that much. The GoodDB (the one that is not logging proc) has 11 rows in Teams and 420 rows in team_project, the BadDB - 4 rows in Teams and about 800 in team_project. It doesn't seem like a bid difference. Is there a way to avoid logging that procedure?

Joe
  • 2,551
  • 6
  • 38
  • 60

2 Answers2

2

Maybe it's not being logged because it uses indexes in those cases. Try running

EXPLAIN SELECT idTeam, name, workersCount, confirmersCount, isConfirm 
FROM Teams JOIN team_project USING (idTeam)
WHERE idProject = p_idProject;

on database where you feel it shouldn't use index and see if it really does. MySql will use index if there is one available and suitable for the query, and if the returning result set is up to about 7-8% of the entire result set.

You say that information_schema is identical, but if the data isn't, that could be a reason for different behavior.

Zagor23
  • 1,953
  • 12
  • 14
2

@Zagor23 explains why this can happen. Your tables are probbaly much bigger in this database and you haven't the appropriate indices.

My advice would be to add a UNIQUE index on table team_project, at (idProject, idTeam)


After the added EXPLAIN outputs, it seems that in the logged case, MySQL optimizer chooses a plan that doesn't need to use any index from the Team table and just scans that whole (4 rows!) table. Which is most probably faster as the table has only 4 rows.

Now, slow-log has some default settings, if I remember well, that adds in the log any query that doesn't use an index, even if the query takes 0.0001 sec to finish.

You can simply ignore this logging or change the slow-log settings to ignore queries that don't use an index. See the MySQL documenation: The Slow Query Log

ypercubeᵀᴹ
  • 113,259
  • 19
  • 174
  • 235
  • If there is a `PRIMARY KEY (idTeam, idProject)` - isn't that pair already `UNIQUE`? – Joe Jul 06 '12 at 06:55
  • 1
    Yes, I mean an index with same columns but in reverse order. It's usual to have these 2 indices in link tables, like this one. You could make this (2nd index) without specifying Unique. But the index is usefeul in various queries. – ypercubeᵀᴹ Jul 06 '12 at 07:22
  • Thx for explanation :) I added the `UNIQUE`. Also I added index on idTeam only (I'm joining using `idTeam'). Unfortunately SP is still being logged. It's quite annoying - this SP is called really and it's noticable while looking through status etc. – Joe Jul 06 '12 at 07:49
  • 1
    I think adding an index on `idTeam` is overhead since there is `PRIMARY KEY (idTeam, idProject)`. If needed, MySql can use only the leading column(s) of concatenated index (in this case `idTeam`), so adding another index on that column just creates more work for MySql on CRUD. – Zagor23 Jul 06 '12 at 07:55
  • I didn't say to add an index on `(idTeam)`. You already have the PK for that. I said to add an index on `(idProject, idTeam)`, unique or not. – ypercubeᵀᴹ Jul 06 '12 at 09:07
  • @ypercube I know. The index on `(idTeam)` was my idea. – Joe Jul 06 '12 at 09:19
  • How much time does the query take? – ypercubeᵀᴹ Jul 06 '12 at 09:23
  • It's not `slow_query`. Usuallyl `Query_time` is about `0.0001xx` – Joe Jul 06 '12 at 09:48
  • If it runs in about a tenth of a ms, I see no reason to spend time on optimizing. You have the `[mysql-slow-query-log]` tag added! – ypercubeᵀᴹ Jul 06 '12 at 09:51
  • @ypercube - Sorry if it's misstagging. I just added this tag, because queries not using indexes are logged to the same file and after global `slow_query_log` is turned on. – Joe Jul 06 '12 at 10:27
  • @Joe: No, I'm rereading your original question and I think it's tagged OK. I suppose you could have added that the query is not slow and the problem is only why it is logged (while not slow!). But I should have read the `rows=4` and `rows=3` in the first place, anyway. – ypercubeᵀᴹ Jul 06 '12 at 10:30
  • @ypercube - I think you're right. Sorry for not noticing this actually important thing on my question. – Joe Jul 06 '12 at 10:40
  • @ypercube: I wrote down what you suggested in to my question. For future readers ;) Thx. – Joe Jul 06 '12 at 10:46