Bug #1690 | UDFs are being called redundantly and causes heavy delays | ||
---|---|---|---|
Submitted: | 28 Oct 2003 14:49 | Modified: | 16 Nov 2003 7:28 |
Reporter: | Ondra Zizka | Email Updates: | |
Status: | Not a Bug | Impact on me: | |
Category: | MySQL Server: User-defined functions ( UDF ) | Severity: | S2 (Serious) |
Version: | 3.23.55 | OS: | Windows (Win32) |
Assigned to: | Sergei Golubchik | CPU Architecture: | Any |
[28 Oct 2003 14:49]
Ondra Zizka
[28 Oct 2003 16:16]
Ondra Zizka
Now I've tried my workaround with the second argument. It doesn't work, because the rows where UDF is called are the ones that passed WHERE contition, thus it will be allways true. Well then, I ask: What is the sense of passing over other convenient rows, and even if it has no system (at least, a system clear to me)... Here I add the log the query generated: - Dot means a UDF has been called - 1st braces contains IP adress (PRIMARY KEY) - 2nd braces contain the 2nd parameter (bool) - + means that gethostbyaddr() was called init .(10.72.128.30) +.(62.24.73.136) +.(65.192.195.15) +.(65.192.195.16) +.(129.187.254.47) +.(192.92.126.162) +.(193.15.53.2) +.(194.102.200.14) +.(194.213.48.50) +.(194.213.208.75) +.(194.228.135.14) + deinit init .(10.72.128.30)+ .(62.24.73.136)+ .(65.192.195.15)+ .(65.192.195.16)+ .(129.187.254.47)+ .(192.92.126.162)+ .(193.15.53.2)+ .(194.102.200.14)+ .(194.213.48.50)+ .(194.213.208.75)+ .(194.228.135.14)+ .(194.228.148.23)+ deinit init .(10.72.128.30)(1)+ .(62.24.73.136)(1)+ .(65.192.195.15)(1)+ .(65.192.195.16)(1)+ .(129.187.254.47)(1)+ .(192.92.126.162)(1)+ .(193.15.53.2)(1)+ .(194.102.200.14)(1)+ .(194.213.48.50)(1)+ .(194.213.208.75)(1)+ .(194.228.135.14)(1)+ .(194.228.148.23)(1)+ .(195.47.108.147)(1)+ .(195.110.172.132)(1)+ .(200.253.207.60)(1)+ .(203.130.212.9)(1)+ .(209.69.41.2)(1)+ .(209.247.40.107)(1)+ .(212.11.100.28)(1)+ deinit Note that every further query seems to skip several rows and return other row. Sometimes I suspect MySQL to do this to not let me bore during long autumn nights... :(( Ondra
[15 Nov 2003 13:36]
Sergei Golubchik
This is not a bug. Here, what happens: mysql> UPDATE ip2dns3 SET dns2 = metaphon(ip) WHERE dns = '-' LIMIT 1; init ...deinit Query OK, 0 rows affected (0.00 sec) Rows matched: 3 Changed: 0 Warnings: 0 as you see I used metaphon() function from udf_example.cc in mysql distribution (where I added fprintf(stderr, ...)) There are 3 rows with dns='-' thus "rows matched" is 3 and metaphon udf was called three times. Limit applies to changed rows, with LIMIT 1 you specify that no more than one row should be changed - indeed you see "Changed: 0" It is because when the new value of the dns2 field is exactly the same as its old value, the row is not changed, limit does not apply, but udf is called. To get the desired effect you may modify your UPDATE by WHERE dns='-' AND dns2='' to avoid resolving ip's that were already resolved
[15 Nov 2003 21:12]
Ondra Zizka
I'm not really convinced that this -------->> Limit applies to changed rows, with LIMIT 1 you specify that no more than one row should be changed - indeed you see "Changed: 0". It is because when the new value of the dns2 field is exactly the same as its old value, the row is not changed, limit does not apply, but udf is called. --------<< really hits my problem. Look, if I have some rows like 123.45.67.89 | somebody.somehost.com 123.45.67.90 | - 123.45.67.91 | - and I do UPDATE ip2dns3 SET dns2 = metaphon(ip) WHERE dns = '-' LIMIT 1, the only rows matched are that one which aren't still resolved.... UH? Man, you got it! I really should blush :) So I should mark not-tried ip's as '' , as the result of my dns_resolve() is '-' if unresolved. Wow that's something I really didn't realize. Sorry for the report. But, anyway, it could be a good demonstration of this feature, could be included in help? Thanks for enlightenment! :) O.Z.
[16 Nov 2003 7:28]
Sergei Golubchik
oops, I just found that the behavior I described is valid for 3.23.x branch only. Since 4.0 LIMIT indeed applies - as you expected - to the number of rows *matched* not *changed*. And it is how UPDATE with LIMIT is documented. Still, it doesn't change anything for you - whatever the LIMIT applies to, you still wouldn't like to resolve the same ip twice :)