0

I have "myfunction" called inside a select "select filed1, filed2, field3, myfunction(parameter) as newfield where conditions having newfield > 0 limit N". Now: inside myfunction I populate a table "cachetable" (using it as a cache) with every single result (record by record) but at the end in "cachetable" the number of rows doesn't respect the LIMIT clause of the main select returning all the records found (if LIMIT wouldn't have been expressed). any help is very appreciated! thanks a lot. d

5
  • What version of MySQL are you using? Each major version has introduced new query optimizations, so it's possible you are using an old version that evaluates the select-list for every row, regardless of LIMIT. See dev.mysql.com/doc/refman/5.6/en/limit-optimization.html and then change the manual version to match the version of MySQL you're using. Commented Jul 16, 2014 at 14:50
  • first of all thanks a lot for your quick response!While you were writing I was taking a look at the same link you posted. at the end I could use my query as is just pulling off the order clause. Now: do you know if I can set a default "order" in a table? for me it would be great sorting it by "createddate" desc Commented Jul 16, 2014 at 15:51
  • by the way, my version is '5.5.23' Commented Jul 16, 2014 at 16:02
  • No, InnoDB tables are always ordered by primary key internally. MyISAM tables (which you should not use anyway) are ordered in an arbitrary way according to the order you created the data. Use ORDER BY. Commented Jul 16, 2014 at 16:02
  • my table id MyISAM. if I use ORDER BY the SELECT "ignore" the LIMIT BY instruction and read all records in the table.. Commented Jul 17, 2014 at 8:37

1 Answer 1

1

I tested this with MySQL 5.5.38, but I could not reproduce the problem you described. If you want further troubleshooting, you'll have to edit your question and give more detail about your query and how you're calling myfunction().

Here's the setup:

USE test;

CREATE TABLE cachetable (
        id INT
);

CREATE TABLE mytable (
        id INT PRIMARY KEY,
        newfield INT
);
INSERT INTO mytable (id, newfield) VALUES
(1, 42), (2, 7), (3, 5), (4, 0), (5, 42), (6, 0);

DELIMITER //
CREATE FUNCTION myfunction (param INT) RETURNS INT
DETERMINISTIC MODIFIES SQL DATA
BEGIN
        INSERT INTO cachetable (id) VALUES (param);
        RETURN 0;
END//
DELIMITER ;

Here's the demo. I tested with and without ORDER BY, and I tested putting the LIMITed query inside a subquery, to ensure that only two rows are returned to the outer query before calling myfunctions(). You can see that no matter how I call it, only two rows are inserted into cachetable.

SELECT *, myfunction(id) FROM mytable WHERE newfield > 0 LIMIT 2;
+----+----------+----------------+
| id | newfield | myfunction(id) |
+----+----------+----------------+
|  1 |       42 |              0 |
|  2 |        7 |              0 |
+----+----------+----------------+

SELECT * FROM cachetable;
+------+
| id   |
+------+
|    1 |
|    2 |
+------+

TRUNCATE cachetable;

SELECT *, myfunction(id) FROM mytable WHERE newfield > 0 ORDER BY newfield LIMIT 2;
+----+----------+----------------+
| id | newfield | myfunction(id) |
+----+----------+----------------+
|  3 |        5 |              0 |
|  2 |        7 |              0 |
+----+----------+----------------+

SELECT * FROM cachetable;
+------+
| id   |
+------+
|    3 |
|    2 |
+------+

TRUNCATE cachetable;

SELECT *, myfunction(id) FROM (SELECT * FROM mytable WHERE newfield > 0 ORDER BY newfield LIMIT 2) AS t;
+----+----------+----------------+
| id | newfield | myfunction(id) |
+----+----------+----------------+
|  3 |        5 |              0 |
|  2 |        7 |              0 |
+----+----------+----------------+

SELECT * FROM cachetable;
+------+
| id   |
+------+
|    3 |
|    2 |
+------+
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.