Re: LIKE sql optimization

2014-02-12 Thread Jesper Wisborg Krogh
On 12/02/2014 13:16, Morgan Tocker wrote:
 Hi Zhigang,

 On Feb 11, 2014, at 8:48 PM, Zhigang Zhang zzgang2...@gmail.com wrote:

 I want to know the reason, in my opinion, to scan the smaller index data has
 better performance than to scan the whole table data. 
 I think I understand the question - you are asking why MySQL will not index 
 scan, find matching records, and then look them up rather than table scan?

 I believe the answer is that there is no way of knowing if 1 row matches, or 
 all rows match.  In the worst case (where all rows match), it is much more 
 expensive to traverse between index and data rows for-each-record.

 So a table scan is a “safe choice / has less variance.

In addition to what Morgan writes, then with an index scan you will end
up doing a lot of random I/O: even if the index scan itself is one
sequential scan (which is not guaranteed) then for each match, it will
be necessary to look up the actual row. On the other hand a table scan
will generally be more of a sequential read as you already have all the
data available for each match. Random I/O is more expensive than
sequential I/O - particularly on spinning disks - so in general the
optimizer will try to reduce the amount of random I/O.

In some cases though, you may see the index scan be preferred. Assume
you have a query like:

SELECT val FROM table WHERE condition LIKE '%abcd';

and you have an index (condition, val) or (val, condition) then the
whole query can be satisfied from the index (it's called a covering
index). In that case the index scan is usually preferred over the table
scan.


For the purpose of using an index to do index lookups to find the
matching rows rather than doing either a table or index scan for WHERE
clauses like LIKE '%abcd' you can do a couple of things:

  * Duplicate the column used in the WHERE clause, but reverse the
string. That way the above WHERE clause becomes: WHERE
condition_revers LIKE 'dcba%'
This can use an index as it is a left prefix.
  * If you always look for around the same number of characters at the
end in your WHERE clause, you can create a column with just those
last characters, e.g. so the WHERE clause becomes: WHERE
condition_suffix = 'abcd'
Do however be careful that you ensure you have enough selectivity
that way. If for example 90% of the rows ends in 'abcd' an index
will not do you much good (unless you are looking for the last 10%
of the rows).


Best regards,
Jesper Krogh
MySQL Support



RE: LIKE sql optimization

2014-02-12 Thread Zhigang Zhang
Done.

 

Thand you very much!

 

Zhigang

 

  _  

From: Jesper Wisborg Krogh [mailto:my...@wisborg.dk] 
Sent: Wednesday, February 12, 2014 5:30 PM
To: Morgan Tocker; Zhigang Zhang
Cc: mysql@lists.mysql.com
Subject: Re: LIKE sql optimization

 

On 12/02/2014 13:16, Morgan Tocker wrote:

Hi Zhigang,
 
On Feb 11, 2014, at 8:48 PM, Zhigang Zhang  mailto:zzgang2...@gmail.com
zzgang2...@gmail.com wrote:
 

I want to know the reason, in my opinion, to scan the smaller index data has
better performance than to scan the whole table data. 

 
I think I understand the question - you are asking why MySQL will not index
scan, find matching records, and then look them up rather than table scan?
 
I believe the answer is that there is no way of knowing if 1 row matches, or
all rows match.  In the worst case (where all rows match), it is much more
expensive to traverse between index and data rows for-each-record.
 
So a table scan is a “safe choice / has less variance.


In addition to what Morgan writes, then with an index scan you will end up
doing a lot of random I/O: even if the index scan itself is one sequential
scan (which is not guaranteed) then for each match, it will be necessary to
look up the actual row. On the other hand a table scan will generally be
more of a sequential read as you already have all the data available for
each match. Random I/O is more expensive than sequential I/O - particularly
on spinning disks - so in general the optimizer will try to reduce the
amount of random I/O.

In some cases though, you may see the index scan be preferred. Assume you
have a query like:

SELECT val FROM table WHERE condition LIKE '%abcd';

and you have an index (condition, val) or (val, condition) then the whole
query can be satisfied from the index (it's called a covering index). In
that case the index scan is usually preferred over the table scan.


For the purpose of using an index to do index lookups to find the matching
rows rather than doing either a table or index scan for WHERE clauses like
LIKE '%abcd' you can do a couple of things:

*   Duplicate the column used in the WHERE clause, but reverse the
string. That way the above WHERE clause becomes: WHERE condition_revers LIKE
'dcba%'
This can use an index as it is a left prefix.
*   If you always look for around the same number of characters at the
end in your WHERE clause, you can create a column with just those last
characters, e.g. so the WHERE clause becomes: WHERE condition_suffix =
'abcd'
Do however be careful that you ensure you have enough selectivity that way.
If for example 90% of the rows ends in 'abcd' an index will not do you much
good (unless you are looking for the last 10% of the rows).


Best regards,
Jesper Krogh
MySQL Support



LIKE sql optimization

2014-02-11 Thread Zhigang Zhang
For example:

 

Select * from T where col like ‘%abcd’;

 

The table T is myisam table and we created a index on col.

 

As we known, this like sql does not use the index created on col, it confuse
me, why?

 

I think in mysiam engine, the index data is smaller, it can use index link
list to optimize it so as to reduce the disk scan than to the whole table
scan.

 

Thanks.

 

Zhigang



Re: LIKE sql optimization

2014-02-11 Thread Reindl Harald


Am 12.02.2014 02:23, schrieb Zhigang Zhang:
 For example:
 
 Select * from T where col like ‘%abcd’;
 
 The table T is myisam table and we created a index on col.
 
 As we known, this like sql does not use the index created on col, it confuse
 me, why?
 
 I think in mysiam engine, the index data is smaller, it can use index link
 list to optimize it so as to reduce the disk scan than to the whole table
 scan

because ‘%abcd’ can't work in case of a index
how do you imagine that?
read how a index works technically

'abcd%' may work but '%abcd' is impossible
independent what engine, this don't work and won't ever work

you may have luck with fulltext search (and it's other drawbacks)
https://dev.mysql.com/doc/refman/5.5/en/fulltext-search.html



signature.asc
Description: OpenPGP digital signature


Re: LIKE sql optimization

2014-02-11 Thread Mathieu Desharnais
Sql database doesn't use index in like statement if it starts with % ..

like 'abcd%' would work though...

To use an index you can store your value using reverse function and index
it .. then your like would use the index.


2014-02-11 20:23 GMT-05:00 Zhigang Zhang zzgang2...@gmail.com:

 For example:



 Select * from T where col like '%abcd';



 The table T is myisam table and we created a index on col.



 As we known, this like sql does not use the index created on col, it
 confuse
 me, why?



 I think in mysiam engine, the index data is smaller, it can use index link
 list to optimize it so as to reduce the disk scan than to the whole table
 scan.



 Thanks.



 Zhigang




RE: LIKE sql optimization

2014-02-11 Thread Zhigang Zhang
I want to know the reason, in my opinion, to scan the smaller index data has
better performance than to scan the whole table data. 

 

 

zhigang

 

  _  

From: Mathieu Desharnais [mailto:mdesharn...@diffusion.cc] 
Sent: Wednesday, February 12, 2014 9:41 AM
To: Zhigang Zhang; mysql@lists.mysql.com
Subject: Re: LIKE sql optimization

 

Sql database doesn't use index in like statement if it starts with % .. 

 

like 'abcd%' would work though... 

 

To use an index you can store your value using reverse function and index it
.. then your like would use the index.

 

2014-02-11 20:23 GMT-05:00 Zhigang Zhang zzgang2...@gmail.com:

For example:



Select * from T where col like ‘%abcd’;



The table T is myisam table and we created a index on col.



As we known, this like sql does not use the index created on col, it confuse
me, why?



I think in mysiam engine, the index data is smaller, it can use index link
list to optimize it so as to reduce the disk scan than to the whole table
scan.



Thanks.



Zhigang

 



Re: LIKE sql optimization

2014-02-11 Thread kitlenv
*read how a index works technically*


On Wed, Feb 12, 2014 at 12:48 PM, Zhigang Zhang zzgang2...@gmail.comwrote:

 I want to know the reason, in my opinion, to scan the smaller index data
 has
 better performance than to scan the whole table data.





 zhigang



   _

 From: Mathieu Desharnais [mailto:mdesharn...@diffusion.cc]
 Sent: Wednesday, February 12, 2014 9:41 AM
 To: Zhigang Zhang; mysql@lists.mysql.com
 Subject: Re: LIKE sql optimization



 Sql database doesn't use index in like statement if it starts with % ..



 like 'abcd%' would work though...



 To use an index you can store your value using reverse function and index
 it
 .. then your like would use the index.



 2014-02-11 20:23 GMT-05:00 Zhigang Zhang zzgang2...@gmail.com:

 For example:



 Select * from T where col like '%abcd';



 The table T is myisam table and we created a index on col.



 As we known, this like sql does not use the index created on col, it
 confuse
 me, why?



 I think in mysiam engine, the index data is smaller, it can use index link
 list to optimize it so as to reduce the disk scan than to the whole table
 scan.



 Thanks.



 Zhigang






Re: LIKE sql optimization

2014-02-11 Thread Reindl Harald
because a index is not just a dumb copy of the whole field
and you simply can't seek in the middle of it?

http://en.wikipedia.org/wiki/B-tree
http://mattfleming.com/node/192

Am 12.02.2014 02:48, schrieb Zhigang Zhang:
 I want to know the reason, in my opinion, to scan the smaller index data has
 better performance than to scan the whole table data. 

 From: Mathieu Desharnais [mailto:mdesharn...@diffusion.cc] 
 Sent: Wednesday, February 12, 2014 9:41 AM
 To: Zhigang Zhang; mysql@lists.mysql.com
 Subject: Re: LIKE sql optimization
 
 Sql database doesn't use index in like statement if it starts with % .. 
 
 like 'abcd%' would work though...   
 
 To use an index you can store your value using reverse function and index it
 .. then your like would use the index.
 
 2014-02-11 20:23 GMT-05:00 Zhigang Zhang zzgang2...@gmail.com:
 
 For example:
 
 Select * from T where col like ‘%abcd’;
 
 The table T is myisam table and we created a index on col.

 As we known, this like sql does not use the index created on col, it confuse
 me, why?
 
 I think in mysiam engine, the index data is smaller, it can use index link
 list to optimize it so as to reduce the disk scan than to the whole table
 scan.



signature.asc
Description: OpenPGP digital signature


Re: LIKE sql optimization

2014-02-11 Thread louis liu
MySQL can't  use index when '%'  condition gives even oracle and you
can try full-text search


2014-02-12 9:55 GMT+08:00 kitlenv kitl...@gmail.com:

 *read how a index works technically*


 On Wed, Feb 12, 2014 at 12:48 PM, Zhigang Zhang zzgang2...@gmail.com
 wrote:

  I want to know the reason, in my opinion, to scan the smaller index data
  has
  better performance than to scan the whole table data.
 
 
 
 
 
  zhigang
 
 
 
_
 
  From: Mathieu Desharnais [mailto:mdesharn...@diffusion.cc]
  Sent: Wednesday, February 12, 2014 9:41 AM
  To: Zhigang Zhang; mysql@lists.mysql.com
  Subject: Re: LIKE sql optimization
 
 
 
  Sql database doesn't use index in like statement if it starts with % ..
 
 
 
  like 'abcd%' would work though...
 
 
 
  To use an index you can store your value using reverse function and index
  it
  .. then your like would use the index.
 
 
 
  2014-02-11 20:23 GMT-05:00 Zhigang Zhang zzgang2...@gmail.com:
 
  For example:
 
 
 
  Select * from T where col like '%abcd';
 
 
 
  The table T is myisam table and we created a index on col.
 
 
 
  As we known, this like sql does not use the index created on col, it
  confuse
  me, why?
 
 
 
  I think in mysiam engine, the index data is smaller, it can use index
 link
  list to optimize it so as to reduce the disk scan than to the whole table
  scan.
 
 
 
  Thanks.
 
 
 
  Zhigang
 
 
 
 




-- 
Phone: +86 1868061
Email  Gtalk:  yloui...@gmail.com
Personal Blog: http://www.vmcd.org


Re: LIKE sql optimization

2014-02-11 Thread Mathieu Desharnais
Same reason as why composite index works only if you supply first field or
fields ..

example index on a,b,c

if you have a query :

select * from tbl
where a = 'whatever'
and b = 'something

it will use the index ..

but a query like this one :

select * from tbl
where b = 'something'
and c = 'something else'

won't use the index ..


-

Just like an index in a book ...




2014-02-11 21:03 GMT-05:00 louis liu yloui...@gmail.com:

 MySQL can't  use index when '%'  condition gives even oracle and you
 can try full-text search


 2014-02-12 9:55 GMT+08:00 kitlenv kitl...@gmail.com:

 *read how a index works technically*



 On Wed, Feb 12, 2014 at 12:48 PM, Zhigang Zhang zzgang2...@gmail.com
 wrote:

  I want to know the reason, in my opinion, to scan the smaller index data
  has
  better performance than to scan the whole table data.
 
 
 
 
 
  zhigang
 
 
 
_
 
  From: Mathieu Desharnais [mailto:mdesharn...@diffusion.cc]
  Sent: Wednesday, February 12, 2014 9:41 AM
  To: Zhigang Zhang; mysql@lists.mysql.com
  Subject: Re: LIKE sql optimization
 
 
 
  Sql database doesn't use index in like statement if it starts with % ..
 
 
 
  like 'abcd%' would work though...
 
 
 
  To use an index you can store your value using reverse function and
 index
  it
  .. then your like would use the index.
 
 
 
  2014-02-11 20:23 GMT-05:00 Zhigang Zhang zzgang2...@gmail.com:
 
  For example:
 
 
 
  Select * from T where col like '%abcd';
 
 
 
  The table T is myisam table and we created a index on col.
 
 
 
  As we known, this like sql does not use the index created on col, it
  confuse
  me, why?
 
 
 
  I think in mysiam engine, the index data is smaller, it can use index
 link
  list to optimize it so as to reduce the disk scan than to the whole
 table
  scan.
 
 
 
  Thanks.
 
 
 
  Zhigang
 
 
 
 




 --
 Phone: +86 1868061
 Email  Gtalk:  yloui...@gmail.com
 Personal Blog: http://www.vmcd.org



RE: LIKE sql optimization

2014-02-11 Thread Zhigang Zhang
I checked a myisam table index, the index is a copy of the whole field.

 

 

Zhigang

 

 

-Original Message-
From: Reindl Harald [mailto:h.rei...@thelounge.net] 
Sent: Wednesday, February 12, 2014 10:02 AM
To: mysql@lists.mysql.com
Subject: Re: LIKE sql optimization

 

because a index is not just a dumb copy of the whole field

and you simply can't seek in the middle of it?

 

http://en.wikipedia.org/wiki/B-tree

http://mattfleming.com/node/192

 

Am 12.02.2014 02:48, schrieb Zhigang Zhang:

 I want to know the reason, in my opinion, to scan the smaller index data
has

 better performance than to scan the whole table data. 

 

 From: Mathieu Desharnais [mailto:mdesharn...@diffusion.cc] 

 Sent: Wednesday, February 12, 2014 9:41 AM

 To: Zhigang Zhang; mysql@lists.mysql.com

 Subject: Re: LIKE sql optimization

 

 Sql database doesn't use index in like statement if it starts with % .. 

 

 like 'abcd%' would work though...   

 

 To use an index you can store your value using reverse function and index
it

 .. then your like would use the index.

 

 2014-02-11 20:23 GMT-05:00 Zhigang Zhang zzgang2...@gmail.com:

 

 For example:

 

 Select * from T where col like ‘%abcd’;

 

 The table T is myisam table and we created a index on col.

 

 As we known, this like sql does not use the index created on col, it
confuse

 me, why?

 

 I think in mysiam engine, the index data is smaller, it can use index link

 list to optimize it so as to reduce the disk scan than to the whole table

 scan.

 



Re: LIKE sql optimization

2014-02-11 Thread Morgan Tocker
Hi Zhigang,

On Feb 11, 2014, at 8:48 PM, Zhigang Zhang zzgang2...@gmail.com wrote:

 I want to know the reason, in my opinion, to scan the smaller index data has
 better performance than to scan the whole table data. 

I think I understand the question - you are asking why MySQL will not index 
scan, find matching records, and then look them up rather than table scan?

I believe the answer is that there is no way of knowing if 1 row matches, or 
all rows match.  In the worst case (where all rows match), it is much more 
expensive to traverse between index and data rows for-each-record.

So a table scan is a “safe choice / has less variance.
--
MySQL General Mailing List
For list archives: http://lists.mysql.com/mysql
To unsubscribe:http://lists.mysql.com/mysql



RE: LIKE sql optimization

2014-02-11 Thread Zhigang Zhang
Thank you very much!

 

Zhigang

 

 

-Original Message-
From: Morgan Tocker [mailto:morgan.toc...@oracle.com] 
Sent: Wednesday, February 12, 2014 10:16 AM
To: Zhigang Zhang
Cc: mysql@lists.mysql.com
Subject: Re: LIKE sql optimization

 

Hi Zhigang,

 

On Feb 11, 2014, at 8:48 PM, Zhigang Zhang zzgang2...@gmail.com wrote:

 

 I want to know the reason, in my opinion, to scan the smaller index data
has

 better performance than to scan the whole table data. 

 

I think I understand the question - you are asking why MySQL will not index
scan, find matching records, and then look them up rather than table scan?

 

I believe the answer is that there is no way of knowing if 1 row matches, or
all rows match.  In the worst case (where all rows match), it is much more
expensive to traverse between index and data rows for-each-record.

 

So a table scan is a “safe choice / has less variance.=



Complex SQL optimization vs. general-purpose language

2010-02-03 Thread Yang Zhang
Any SQL rewriting gurus know how I might be able to optimize this
query? The schema:

mysql show columns from transactionlog;
+---+---+--+-+-++
| Field | Type  | Null |
Key | Default | Extra  |
+---+---+--+-+-++
| id| int(11)   | NO   |
PRI | NULL| auto_increment |
| transactionid | varchar(10)   | NO   |
MUL | NULL||
| queryid   | tinyint(4)| NO   |
  | NULL||
| tableid   | varchar(30)   | NO   |
MUL | NULL||
| tupleid   | int(11)   | NO   |
  | NULL||
| querytype | enum('select','insert','delete','update') | NO   |
  | NULL||
| schemaname| varchar(20)   | YES  |
  | NULL||
| partition | tinyint(3) unsigned   | YES  |
  | NULL||
+---+---+--+-+-++
8 rows in set (0.04 sec)

The query:

select concat(weight, ' ', ids, '\n')
from (
  select
tableid,
tupleid,
group_concat(id separator ' ') as ids,
(
  select count(distinct transactionid)
  from transactionlog
  where transactionid in (
select transactionid
from transactionlog
where (tableid, tupleid, querytype) =
  (t.tableid, t.tupleid, 'update')
group by transactionid
having count(*)  0
  )
) weight
  from transactionlog t
  group by tableid, tupleid
  having weight  0 and count(*)  1
) u;

This is the output of EXPLAIN and mk-visual-explain:

++++---+---+---+-+---+--+--
+
| id | select_type| table  | type  | possible_keys |
key   | key_len | ref   | rows | Extra
   |
++++---+---+---+-+---+--+--+
|  1 | PRIMARY| derived2 | ALL   | NULL  |
NULL  | NULL| NULL  |   13 |
   |
|  2 | DERIVED| t  | ALL   | NULL  |
NULL  | NULL| NULL  |   68 | Using filesort
   |
|  3 | DEPENDENT SUBQUERY | transactionlog | index | NULL  |
transactionid | 12  | NULL  |   68 | Using where; Using index
   |
|  4 | DEPENDENT SUBQUERY | transactionlog | ref   | tableid   |
tableid   | 36  | func,func |2 | Using where; Using
temporary; Using filesort |
++++---+---+---+-+---+--+--+
Table scan
rows   13
+- DERIVED
   table  derived(t,transactionlog,temporary(transactionlog))
   +- DEPENDENT SUBQUERY
  +- DEPENDENT SUBQUERY
  |  +- Filesort
  |  |  +- TEMPORARY
  |  | table  temporary(transactionlog)
  |  | +- Filter with WHERE
  |  |+- Bookmark lookup
  |  |   +- Table
  |  |   |  table  transactionlog
  |  |   |  possible_keys  tableid
  |  |   +- Index lookup
  |  |  keytransactionlog-tableid
  |  |  possible_keys  tableid
  |  |  key_len36
  |  |  reffunc,func
  |  |  rows   2
  |  +- Filter with WHERE
  | +- Index scan
  |keytransactionlog-transactionid
  |key_len12
  |rows   68
  +- Filesort
 +- Table scan
rows   68
+- Table
   table  t

That is a lot of work. I can write the equivalent logic in Python
while making a single pass:

  results = query(
select tableid, tupleid, transactionid, id, querytype
from transactionlog_2warehouse
  )
  _tab, _tup = None
  ids = []
  weight = 0
  saw_upd = False
  for tab, tup, txn, id, qt in results:
if (_tab, _tup) != (tab, tup):
  if len(ids)  1 and weight  0:
print weight, ids
  weight = 0
  ids = []
  _txn = None
if _txn != txn:
  saw_upd = False
if qt == 'update' and not saw_upd:
  weight += 1
  saw_upd = True
ids += [id]

Is it possible to achieve the Python single-pass performance using
pure SQL? Thanks in advance!
-- 
Yang Zhang
http://www.mit.edu/~y_z/


Ugly sql optimization help?

2007-09-25 Thread Bryan Cantwell
I have the following horrible sql. I need one result that has all the
data in one row. I am currently using 3 sub queries and figure it must
be a better way...

SELECT 'FS_DEV',


ifnull(a.severity, 0) AS aseverity, 

ifnull(a.eventid, 0) AS aeventid,  

ifnull(a.description, 'None') AS adescription,  
ifnull(a.hostid,
0) AS ahostid,  

ifnull(a.color,'#E5E0DC') as acolor,  

ifnull(a.fontcolor,0) as afontcolor,  

ifnull(a.severitydesc,'None') as aseveritydesc,  

ifnull(p.severity, 0) AS pseverity,  

ifnull(p.eventid, 0) AS peventid,  

ifnull(p.description, 'None') AS pdescription,  
ifnull(p.hostid,
0) AS phostid,  

ifnull(p.color,'#E5E0DC') as pcolor,  

ifnull(p.fontcolor,0) as pfontcolor,  

ifnull(p.severitydesc,'None') as pseveritydesc,  

ifnull(s.severity, 0) AS sseverity,  

ifnull(s.eventid, 0) AS seventid,  

ifnull(s.description, 'None') AS sdescription,  
ifnull(s.hostid,
0) AS shostid,  

ifnull(s.color,'#E5E0DC') as scolor,  

ifnull(s.fontcolor,0) as sfontcolor,  

ifnull(s.severitydesc,'None') as sseveritydesc  
FROM  
(SELECT
e.severity, e.eventid, e.description,  
e.hostid,
fs.color, fs.fontcolor, fs.severitydesc  
FROM fs_events
e, fs_severity fs  
WHERE hostid in
(21,22,23,24,15,16)
and e.severity =
fs.severityid 
AND e.event_perf
= 1 
AND e.time_stamp
= date_sub(now(), INTERVAL 30 DAY)  
AND
e.acknowledged in ( 0,1)  
ORDER BY
e.severity DESC, e.time_stamp DESC LIMIT 0, 1) p,
(SELECT
e.severity, e.eventid, e.description,  
e.hostid,
fs.color, fs.fontcolor, fs.severitydesc  
FROM fs_events
e, fs_severity fs  
WHERE hostid in
(21,22,23,24,15,16)
and e.severity =
fs.severityid 
AND
e.event_avail = 1 
AND e.time_stamp
= date_sub(now(), INTERVAL 30 DAY)  
AND
e.acknowledged in ( 0,1)  
ORDER BY
e.severity DESC, e.time_stamp DESC LIMIT 0, 1) a,
(SELECT
e.severity, e.eventid, e.description,  
e.hostid,
fs.color, fs.fontcolor, fs.severitydesc  
FROM fs_events
e, fs_severity fs  
WHERE hostid in
(21,22,23,24,15,16)
and e.severity =
fs.severityid 
AND e.event_sec
= 1 
AND e.time_stamp
= date_sub(now(), INTERVAL 30 DAY)  
AND
e.acknowledged in ( 0,1)  
ORDER BY
e.severity DESC, e.time_stamp DESC LIMIT 0, 1) s

--
MySQL General Mailing List
For list archives: http://lists.mysql.com/mysql
To unsubscribe:http://lists.mysql.com/[EMAIL PROTECTED]



Need sql optimization help

2007-03-03 Thread Bryan Cantwell
I have the following sql that works for what I want to see but is
terribly slow due to the subquery. Any suggestions on how to get same
result faster? I have tried group by and cant seem to get the correct
results that way

Also is there a product that can help optimize sql and indexing?

SELECT DISTINCT e.severity, e.time_stamp, replace(e.description,
'{HOSTNAME}', h.host) AS description, h.host, h.hostid, e.value,
e.triggerid, s.color FROM fs_events e, hosts h, fs_severity s WHERE
e.hostid = 10011 AND e.hostid = h.hostid AND e.time_stamp = (SELECT
max(time_stamp) FROM fs_events WHERE triggerid = e.triggerid) and
e.severity = s.severityid ORDER BY e.time_stamp DESC

--
MySQL General Mailing List
For list archives: http://lists.mysql.com/mysql
To unsubscribe:http://lists.mysql.com/[EMAIL PROTECTED]



Re: Need sql optimization help

2007-03-03 Thread Peter Brawley

Bryan,

A 'Not Exists' query 
http://www.artfulsoftware.com/infotree/queries.php#41 is usually 
faster when coded as an exclusion join, eg for max-some-value per key, 
left join on the key variable and left.value  right. value where 
left.key is null, so you would need something like ...


SELECT DISTINCT
 e.severity,
 e.time_stamp,
 replace(e.description,'{HOSTNAME}', h.host) AS description,
 h.host,
 h.hostid,
 e.value,
 e.triggerid,
 s.color
FROM fs_events e
JOIN  hosts h USING (hostid)
JOIN fs_severity s ON (e.severity = s.severityid)
LEFT JOIN fs_events e2
 ON e.triggerid=e2.triggerid
 AND e.MAX(time_stamp)  e2.MAX(time_stamp)
WHERE e.hostid = 10011
 AND e2.triggerid IS NULL
ORDER BY e.time_stamp DESC

PB

Bryan Cantwell wrote:

I have the following sql that works for what I want to see but is
terribly slow due to the subquery. Any suggestions on how to get same
result faster? I have tried group by and cant seem to get the correct
results that way

Also is there a product that can help optimize sql and indexing?

SELECT DISTINCT e.severity, e.time_stamp, replace(e.description,
'{HOSTNAME}', h.host) AS description, h.host, h.hostid, e.value,
e.triggerid, s.color FROM fs_events e, hosts h, fs_severity s WHERE
e.hostid = 10011 AND e.hostid = h.hostid AND e.time_stamp = (SELECT
max(time_stamp) FROM fs_events WHERE triggerid = e.triggerid) and
e.severity = s.severityid ORDER BY e.time_stamp DESC

  


RE: Need sql optimization help

2007-03-03 Thread Bryan Cantwell
Gives me invalid use of group function:

 

SELECT DISTINCT 

e.severity, 

e.time_stamp, 

replace(e.description,'{HOSTNAME}', h.host) AS description, 

h.host, 

h.hostid, 

e.value,

e.triggerid, 

s.color 

FROM fs_events e

JOIN hosts h USING (hostid)

JOIN fs_severity s ON (e.severity = s.severityid)

LEFT JOIN fs_events e2 

ON e.triggerid=e2.triggerid 

AND MAX(e.time_stamp)  MAX(e2.time_stamp)

WHERE e.hostid = 10011 

AND e2.triggerid IS NULL 

ORDER BY e.time_stamp DESC




From: Peter Brawley [mailto:[EMAIL PROTECTED] 
Sent: Saturday, March 03, 2007 1:40 PM
To: Bryan Cantwell
Cc: mysql@lists.mysql.com
Subject: Re: Need sql optimization help


Bryan,

A 'Not Exists' query
http://www.artfulsoftware.com/infotree/queries.php#41  is usually
faster when coded as an exclusion join, eg for max-some-value per key,
left join on the key variable and left.value  right. value where
left.key is null, so you would need something like ...

SELECT DISTINCT 
  e.severity, 
  e.time_stamp, 
  replace(e.description,'{HOSTNAME}', h.host) AS description, 
  h.host, 
  h.hostid, 
  e.value,
  e.triggerid, 
  s.color 
FROM fs_events e
JOIN  hosts h USING (hostid)
JOIN fs_severity s ON (e.severity = s.severityid)
LEFT JOIN fs_events e2 
  ON e.triggerid=e2.triggerid 
  AND e.MAX(time_stamp)  e2.MAX(time_stamp)
WHERE e.hostid = 10011 
  AND e2.triggerid IS NULL 
ORDER BY e.time_stamp DESC

PB

Bryan Cantwell wrote: 

I have the following sql that works for what I want to see but
is
terribly slow due to the subquery. Any suggestions on how to get
same
result faster? I have tried group by and cant seem to get the
correct
results that way

Also is there a product that can help optimize sql and indexing?

SELECT DISTINCT e.severity, e.time_stamp, replace(e.description,
'{HOSTNAME}', h.host) AS description, h.host, h.hostid, e.value,
e.triggerid, s.color FROM fs_events e, hosts h, fs_severity s
WHERE
e.hostid = 10011 AND e.hostid = h.hostid AND e.time_stamp =
(SELECT
max(time_stamp) FROM fs_events WHERE triggerid = e.triggerid)
and
e.severity = s.severityid ORDER BY e.time_stamp DESC

  



Re: Need sql optimization help

2007-03-03 Thread Michael Dykman

Your inner query guarantees that MySQL will have to test an awfull lot
of combinations:   (# of records in fs_events)^2 *  (# of records in
hosts) * (# of records in severity)

(SELECT max(time_stamp) FROM fs_events WHERE triggerid = e.triggerid)
needs to be recalculated every time we try to match a row in the outer
query..   that is going to hurt a lot.

- michael dykman


On 3/3/07, Bryan Cantwell [EMAIL PROTECTED] wrote:

Gives me invalid use of group function:



SELECT DISTINCT

e.severity,

e.time_stamp,

replace(e.description,'{HOSTNAME}', h.host) AS description,

h.host,

h.hostid,

e.value,

e.triggerid,

s.color

FROM fs_events e

JOIN hosts h USING (hostid)

JOIN fs_severity s ON (e.severity = s.severityid)

LEFT JOIN fs_events e2

ON e.triggerid=e2.triggerid

AND MAX(e.time_stamp)  MAX(e2.time_stamp)

WHERE e.hostid = 10011

AND e2.triggerid IS NULL

ORDER BY e.time_stamp DESC




From: Peter Brawley [mailto:[EMAIL PROTECTED]
Sent: Saturday, March 03, 2007 1:40 PM
To: Bryan Cantwell
Cc: mysql@lists.mysql.com
Subject: Re: Need sql optimization help


Bryan,

A 'Not Exists' query
http://www.artfulsoftware.com/infotree/queries.php#41  is usually
faster when coded as an exclusion join, eg for max-some-value per key,
left join on the key variable and left.value  right. value where
left.key is null, so you would need something like ...

SELECT DISTINCT
  e.severity,
  e.time_stamp,
  replace(e.description,'{HOSTNAME}', h.host) AS description,
  h.host,
  h.hostid,
  e.value,
  e.triggerid,
  s.color
FROM fs_events e
JOIN  hosts h USING (hostid)
JOIN fs_severity s ON (e.severity = s.severityid)
LEFT JOIN fs_events e2
  ON e.triggerid=e2.triggerid
  AND e.MAX(time_stamp)  e2.MAX(time_stamp)
WHERE e.hostid = 10011
  AND e2.triggerid IS NULL
ORDER BY e.time_stamp DESC

PB

Bryan Cantwell wrote:

I have the following sql that works for what I want to see but
is
terribly slow due to the subquery. Any suggestions on how to get
same
result faster? I have tried group by and cant seem to get the
correct
results that way

Also is there a product that can help optimize sql and indexing?

SELECT DISTINCT e.severity, e.time_stamp, replace(e.description,
'{HOSTNAME}', h.host) AS description, h.host, h.hostid, e.value,
e.triggerid, s.color FROM fs_events e, hosts h, fs_severity s
WHERE
e.hostid = 10011 AND e.hostid = h.hostid AND e.time_stamp =
(SELECT
max(time_stamp) FROM fs_events WHERE triggerid = e.triggerid)
and
e.severity = s.severityid ORDER BY e.time_stamp DESC







--
- michael dykman
- [EMAIL PROTECTED]

--
MySQL General Mailing List
For list archives: http://lists.mysql.com/mysql
To unsubscribe:http://lists.mysql.com/[EMAIL PROTECTED]



Re: Need sql optimization help

2007-03-03 Thread Peter Brawley

Sorry for the typo, lose the MAX! ...

SELECT DISTINCT
 e.severity,
 e.time_stamp,
 replace(e.description,'{HOSTNAME}', h.host) AS description,
 h.host,
 h.hostid,
 e.value,
 e.triggerid,
 s.color
FROM fs_events e
JOIN  hosts h USING (hostid)
JOIN fs_severity s ON (e.severity = s.severityid)
LEFT JOIN fs_events e2
 ON e.triggerid=e2.triggerid
 AND e.time_stamp  e2.time_stamp
WHERE e.hostid = 10011
 AND e2.triggerid IS NULL
ORDER BY e.time_stamp DESC

PB

Michael Dykman wrote:

Your inner query guarantees that MySQL will have to test an awfull lot
of combinations:   (# of records in fs_events)^2 *  (# of records in
hosts) * (# of records in severity)

(SELECT max(time_stamp) FROM fs_events WHERE triggerid = e.triggerid)
needs to be recalculated every time we try to match a row in the outer
query..   that is going to hurt a lot.

- michael dykman


On 3/3/07, Bryan Cantwell [EMAIL PROTECTED] wrote:

Gives me invalid use of group function:



SELECT DISTINCT

e.severity,

e.time_stamp,

replace(e.description,'{HOSTNAME}', h.host) AS description,

h.host,

h.hostid,

e.value,

e.triggerid,

s.color

FROM fs_events e

JOIN hosts h USING (hostid)

JOIN fs_severity s ON (e.severity = s.severityid)

LEFT JOIN fs_events e2

ON e.triggerid=e2.triggerid

AND MAX(e.time_stamp)  MAX(e2.time_stamp)

WHERE e.hostid = 10011

AND e2.triggerid IS NULL

ORDER BY e.time_stamp DESC




From: Peter Brawley [mailto:[EMAIL PROTECTED]
Sent: Saturday, March 03, 2007 1:40 PM
To: Bryan Cantwell
Cc: mysql@lists.mysql.com
Subject: Re: Need sql optimization help


Bryan,

A 'Not Exists' query
http://www.artfulsoftware.com/infotree/queries.php#41  is usually
faster when coded as an exclusion join, eg for max-some-value per key,
left join on the key variable and left.value  right. value where
left.key is null, so you would need something like ...

SELECT DISTINCT
  e.severity,
  e.time_stamp,
  replace(e.description,'{HOSTNAME}', h.host) AS description,
  h.host,
  h.hostid,
  e.value,
  e.triggerid,
  s.color
FROM fs_events e
JOIN  hosts h USING (hostid)
JOIN fs_severity s ON (e.severity = s.severityid)
LEFT JOIN fs_events e2
  ON e.triggerid=e2.triggerid
  AND e.MAX(time_stamp)  e2.MAX(time_stamp)
WHERE e.hostid = 10011
  AND e2.triggerid IS NULL
ORDER BY e.time_stamp DESC

PB

Bryan Cantwell wrote:

I have the following sql that works for what I want to see but
is
terribly slow due to the subquery. Any suggestions on how to get
same
result faster? I have tried group by and cant seem to get the
correct
results that way

Also is there a product that can help optimize sql and indexing?

SELECT DISTINCT e.severity, e.time_stamp, replace(e.description,
'{HOSTNAME}', h.host) AS description, h.host, h.hostid, e.value,
e.triggerid, s.color FROM fs_events e, hosts h, fs_severity s
WHERE
e.hostid = 10011 AND e.hostid = h.hostid AND e.time_stamp =
(SELECT
max(time_stamp) FROM fs_events WHERE triggerid = e.triggerid)
and
e.severity = s.severityid ORDER BY e.time_stamp DESC









--
MySQL General Mailing List
For list archives: http://lists.mysql.com/mysql
To unsubscribe:http://lists.mysql.com/[EMAIL PROTECTED]



Sql optimization

2006-06-20 Thread prasad.ramisetti
Hi All,

I am usingINNODB.I have a delete quetry something like this :

delete from modnaptrrecord_zone where
modnaptrrecord_zone.modnaptrrecord_id in (593536 ,593537 ,593538 ,593539 ,593540
) and modnaptrrecord_zone.modnaptrrecord_id not in (593536
)

This is taking a verylong time
to execute..somewhere around 15mins. The values in the "id in"and "not
in" of the where clause are around 1. I am sending the "SHOW INNODB STATUS
also. Can somebody let me know, why this is taking such a long time ? And how to
optimize this query ?

Thanks
Prasad

The information contained in this electronic message and any attachments to this message are intended for the exclusive use of the addressee(s) and may contain proprietary, confidential or privileged information. If you are not the intended recipient, you should not disseminate, distribute or copy this e-mail. Please notify the sender immediately and destroy all copies of this message and any attachments. 

WARNING: Computer viruses can be transmitted via email. The recipient should check this email and any attachments for the presence of viruses. The company accepts no liability for any damage caused by any virus transmitted by this email.
 
www.wipro.com


[EMAIL PROTECTED] /usr/local/mysql/bin/mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 27 to server version: 4.1.7-standard

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql use ipworks
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql show innodb status
- ;

Re: Sql optimization

2006-06-20 Thread Rhino



You're hard-coding ten thousand discrete 
values between the two IN clauses?? I'm not sure how MySQL processes a query 
like that but I can imagine that the performance would not be good. Frankly, I 
am: 
a)suprised that you had the patience 
to type in all of those values (andverify that you typed them 
correctly)
b) amazed that MySQL actually executes a 
statement that long without complaining that the statement is too 
long

Are the discrete values really sequential 
like the example you show? Because if they are you might find your life a lot 
easier if you simply write your INs as BETWEENs. For example, 


delete from modnaptrrecord_zone 

where 
modnaptrrecord_zone.modnaptrrecord_idbetween 593536 and 789123and 
modnaptrrecord_zone.modnaptrrecord_id notbetween 593536 and 
789123

Even if there were a few ranges, the 
query would still be a lot shorter if written with BETWEENs. For 
example,


delete from modnaptrrecord_zone 

where 
(modnaptrrecord_zone.modnaptrrecord_id (between 100 and 500)
or 
(modnaptrecord_zone.modnaptrrecord_id between 1 and 11000)) 
and 
(modnaptrrecord_zone.modnaptrrecord_id not (between 100 and 500)
or 
(modnaptrecord_zone.modnaptrrecord_id between 1 and 11000)) 

I've probably got at least one of 
those conditions backward but you probably get the idea. It's a LOT easier to 
write ranges than long lists of sequential values!

Another way that might improve 
performance a lot is if you use a subqueries with your IN clauses. For 
example:


delete from modnaptrrecord_zone 

where 
modnaptrrecord_zone.modnaptrrecord_id in 
(select id from other_table where 
customer_country = 'USA') and 
modnaptrrecord_zone.modnaptrrecord_id 
not in 
(select id from other_table where 
customer_country = 'CANADA')

In other words, if the values that 
need to go into the IN list can be obtained by reading a table with a SELECT, 
put the SELECT statement within the brackets instead of listing the hundreds of 
discrete values. Of course, this assumes that you are using a version of MySQL 
that supports subqueries!!

By the way, I'm assuming that the 
lists needed for your two IN clauses are different from one another in some 
way.Your query makes no sense if the two lists are the same. For example, 
if your lists were the same - I'll just use a few values for each list to make 
my point clear - you might have a query like this:


delete from modnaptrrecord_zone 

where 
modnaptrrecord_zone.modnaptrrecord_id in (1, 2, 3) and 
modnaptrrecord_zone.modnaptrrecord_id 
not in (1, 2, 3)

In other words, you want to delete 
rows in table modnaprrecord_zone where the modnaptrrecord_id IS 1, 2 or 3 AND 
where the mondaptrrecord_id IS NOT 1, 2, or 3 at the same time. That doesn't 
make sense.

Now, if the values in the lists are 
not in ranges and can't easily be obtained via SELECT queries, you may want to 
consider modifying your tables to simplify this query. Let's say that those long 
IN lists are just trying to specify customers who are in good standing with you, 
i.e. customers who don't owe you any money and are prompt to pay their accounts. 
You might find it a lot easier to add a column to your customer table that 
indicates the customer's status and then simply search on the value of that 
status flag. For example, let's say that a customer could have three statuses: 
"Excellent", "Good" and "Poor". You could have a process that determines the 
proper status for that customer; that might be a batch job that runs once a day 
or once a week. Then, your query could simply search for the status like 
this:


delete from modnaptrrecord_zone where 
modnaptrrecord_zone.modnaptrrecord_id in 
(select id from customer where status 
= 'Poor') and 
modnaptrrecord_zone.modnaptrrecord_id 
not in 
(select id from customer where status 
= 'Good')

--
Rhino

  - Original Message - 
  From: 
  [EMAIL PROTECTED] 
  To: mysql@lists.mysql.com 
  Sent: Tuesday, June 20, 2006 11:22 
  AM
  Subject: Sql optimization
  
  Hi All,
  
  I am usingINNODB.I have a delete quetry something like this :
  
  delete from modnaptrrecord_zone 
  where modnaptrrecord_zone.modnaptrrecord_id in (593536 ,593537 ,593538 ,593539 
  ,593540 ) and modnaptrrecord_zone.modnaptrrecord_id not in (593536 
  )
  
  This is taking a verylong 
  time to execute..somewhere around 15mins. The values in the "id 
  in"and "not in" of the where clause are around 1. I am sending 
  the "SHOW INNODB STATUS also. Can somebody let me know, why this is taking 
  such a long time ? And how to optimize this query ?
  
  Thanks
  Prasad
  


  The information contained in this electronic message 
and any attachments to this message are intended for the exclusive use 
of the addressee(s) and may contain proprietary, confidential or 
privileged information. If you are not the intended recipient, you 
should 

Re: Sql optimization

2006-06-20 Thread Pooly

2006/6/20, [EMAIL PROTECTED] [EMAIL PROTECTED]:




Hi All,

I am using INNODB.I have a delete quetry something like this :

delete from modnaptrrecord_zone where modnaptrrecord_zone.modnaptrrecord_id in 
(593536 ,593537 ,593538 ,593539 ,593540 ) and 
modnaptrrecord_zone.modnaptrrecord_id not in (593536 )


I hope this is just some quick copy/paste, but if in your query you
have : IN (A, B) AND NOT IN (A,B), I don't think it will return much
data...
Is there any index on modnaptrrecord_zone.modnaptrrecord_id ?
ALTER TABLE modnaptrrecord_zone ADD INDEX(modnaptrrecord_id);
Where did you get the list of ids ? you may be better off using a
temporary table and doing an inner or left join on it.


--
http://www.w-fenec.org/

--
MySQL General Mailing List
For list archives: http://lists.mysql.com/mysql
To unsubscribe:http://lists.mysql.com/[EMAIL PROTECTED]



Re: SQL optimization problem

2003-01-11 Thread Bhavin Vyas
You might have to tweak the following a bit for syntax:

SELECT a.name, COUNT(b.id) as votes FROM poll_options as a LEFT JOIN
poll_votes as b ON  a.id=b.oid
 WHERE b.pid='poll_id' GROUP BY b.oid

Also, you can refer to:

http://www.mysql.com/doc/en/JOIN.html

Bhavin.


- Original Message -
From: Blaster [EMAIL PROTECTED]
To: [EMAIL PROTECTED]
Sent: Saturday, January 11, 2003 12:35 PM
Subject: SQL optimization problem


 Hey,

 (this post is pretty long, a short version of the problem is listed at the
 bottom if you don't like reading long emails :P)

 I'm currently going through all my SQL queries for my webpage to see if
 there is anything I can do to optimize them.
 On my webpage, i have this poll where people can give their opinion in
 various subjects by casting a vote. To begin
 with, I'd like to tell you how I created my tables for this task, the poll
 uses in total 3 different tables as following:

 poll_list (this table contains the actual question of each poll)
 ===
 id (int) | stamp (datetime) | question (varchar 255) | active (tinyint)

 Id is simply an autoincrementing ID for each poll,

 Stamp is the creation date of the poll,

 Question holds the actual question (duh :P)

 If Active is 1, it means that this is the active poll right now.
 Only one poll can be active at the same time.

 poll_options (this table holds the valid answers for each poll. You may
use
 any number of answers in your poll)



 id (int) | pid (int) | name (varchar 255)

 id is again, autoinc field for this answer

 pid is a pointer to which poll this particular answer belongs to, i.e pid
=
 poll_list.id

 name holds the actual answer string

 poll_votes (this table holds all the casted votes, one row is one vote)
 =
 id (int) | pid (int) | oid (int) | uid (int)

 id, autoinc

 pid, pointer to poll_list.id, tells me which poll this vote belongs to

 oid, pointer to poll_options.id, tells me which option this user voted

 uid, pointer to user account. I won't include the user table, just think
of
 this as a unique identifier
 for the users, prevents the same user from voting twice in a poll..


 AND now! to the problem! Prior to my optimzation checking began, the
code
 to display the
 results of a poll was something like this:

 1) Fetch the active poll:
 SELECT * FROM poll_list WHERE (active  0) ORDER BY stamp DESC LIMIT 1

 2) Fetch the answers for the poll ID we received from the prior query:
 SELECT * FROM poll_options WHERE pid='id_from_prior_query'

 3) For each option received in step 2, I did:
 SELECT * FROM poll_votes WHERE pid='poll_id' AND oid='option_id'

 4) Output HTML formated code to web visitor.

 Now, I thought, it MUST be possible to make step 2 and 3 using 1 single
 query, because using this old
 system (as shown above), it requires 1 + n queries, where n is number of
 answers in that particular poll.

 So, I simply replaced it with:

 1) Fetch the active poll:
 SELECT * FROM poll_list WHERE (active  0) ORDER BY stamp DESC LIMIT 1

 2) Fetch the answers  votes in the same query:
 SELECT a.name, COUNT(b.id) as votes FROM poll_options as a, poll_votes as
b
 WHERE b.pid='poll_id' AND b.oid=a.id GROUP BY b.oid

 3) Print the results.

  PROBLEM BEGINS HERE ##

 However! Here comes the problem, if no vote is cast on an option, it will
 not show up in the list! I want it to print 0%
 for any options that havn't received a vote, like it would with my old
 query system. This is basically what I want to
 do:

 Select all options from poll_options and, in the same query, count the
 number of rows in poll_votes which has that
 particular options id as oid. Pretty hard to explain, but ideally, I'd
 like to do

 SELECT a.name, COUNT(b.id) as votes FROM poll_options as a, poll_votes as
b
 WHERE b.pid='poll_id' AND b.oid=a.id GROUP BY b.oid

 With one exception, if votes = 0, it should be listed in the result
aswell!


 -
 Before posting, please check:
http://www.mysql.com/manual.php   (the manual)
http://lists.mysql.com/   (the list archive)

 To request this thread, e-mail [EMAIL PROTECTED]
 To unsubscribe, e-mail mysql-unsubscribe-##L=##[EMAIL PROTECTED]
 Trouble unsubscribing? Try: http://lists.mysql.com/php/unsubscribe.php



-
Before posting, please check:
   http://www.mysql.com/doc/ (the manual)
   http://lists.mysql.com/   (the list archive)

To request this thread, e-mail [EMAIL PROTECTED]
To unsubscribe, e-mail mysql-unsubscribe-##L=##[EMAIL PROTECTED]
Trouble unsubscribing? Try: http://lists.mysql.com/php/unsubscribe.php




Re: SQL optimization problem

2003-01-11 Thread Michael Brunson
LEFT JOIN


On Sat, 11 Jan 2003 18:35:44 +0100, Blaster used a few
recycled electrons to form:

| Hey,
| 
| (this post is pretty long, a short version of the problem is listed at the 
| bottom if you don't like reading long emails :P)
| 
| I'm currently going through all my SQL queries for my webpage to see if 
| there is anything I can do to optimize them.
| On my webpage, i have this poll where people can give their opinion in 
| various subjects by casting a vote. To begin
| with, I'd like to tell you how I created my tables for this task, the poll 
| uses in total 3 different tables as following:
| 
| poll_list (this table contains the actual question of each poll)
| ===
| id (int) | stamp (datetime) | question (varchar 255) | active (tinyint)
| 
| Id is simply an autoincrementing ID for each poll,
| 
| Stamp is the creation date of the poll,
| 
| Question holds the actual question (duh :P)
| 
| If Active is 1, it means that this is the active poll right now.
| Only one poll can be active at the same time.
| 
| poll_options (this table holds the valid answers for each poll. You may use 
| any number of answers in your poll)
| 
| id (int) | pid (int) | name (varchar 255)
| 
| id is again, autoinc field for this answer
| 
| pid is a pointer to which poll this particular answer belongs to, i.e pid = 
| poll_list.id
| 
| name holds the actual answer string
| 
| poll_votes (this table holds all the casted votes, one row is one vote)
| =
| id (int) | pid (int) | oid (int) | uid (int)
| 
| id, autoinc
| 
| pid, pointer to poll_list.id, tells me which poll this vote belongs to
| 
| oid, pointer to poll_options.id, tells me which option this user voted
| 
| uid, pointer to user account. I won't include the user table, just think of 
| this as a unique identifier
| for the users, prevents the same user from voting twice in a poll..
| 
| 
| AND now! to the problem! Prior to my optimzation checking began, the code 
| to display the
| results of a poll was something like this:
| 
| 1) Fetch the active poll:
| SELECT * FROM poll_list WHERE (active  0) ORDER BY stamp DESC LIMIT 1
| 
| 2) Fetch the answers for the poll ID we received from the prior query:
| SELECT * FROM poll_options WHERE pid='id_from_prior_query'
| 
| 3) For each option received in step 2, I did:
| SELECT * FROM poll_votes WHERE pid='poll_id' AND oid='option_id'
| 
| 4) Output HTML formated code to web visitor.
| 
| Now, I thought, it MUST be possible to make step 2 and 3 using 1 single 
| query, because using this old
| system (as shown above), it requires 1 + n queries, where n is number of 
| answers in that particular poll.
| 
| So, I simply replaced it with:
| 
| 1) Fetch the active poll:
| SELECT * FROM poll_list WHERE (active  0) ORDER BY stamp DESC LIMIT 1
| 
| 2) Fetch the answers  votes in the same query:
| SELECT a.name, COUNT(b.id) as votes FROM poll_options as a, poll_votes as b 
| WHERE b.pid='poll_id' AND b.oid=a.id GROUP BY b.oid
| 
| 3) Print the results.
| 
|  PROBLEM BEGINS HERE ##
| 
| However! Here comes the problem, if no vote is cast on an option, it will 
| not show up in the list! I want it to print 0%
| for any options that havn't received a vote, like it would with my old 
| query system. This is basically what I want to
| do:
| 
| Select all options from poll_options and, in the same query, count the 
| number of rows in poll_votes which has that
| particular options id as oid. Pretty hard to explain, but ideally, I'd 
| like to do
| 
| SELECT a.name, COUNT(b.id) as votes FROM poll_options as a, poll_votes as b 
| WHERE b.pid='poll_id' AND b.oid=a.id GROUP BY b.oid
| 
| With one exception, if votes = 0, it should be listed in the result aswell!
| 
| 
| -
| Before posting, please check:
|http://www.mysql.com/manual.php   (the manual)
|http://lists.mysql.com/   (the list archive)
| 
| To request this thread, e-mail [EMAIL PROTECTED]
| To unsubscribe, e-mail mysql-unsubscribe-##L=##[EMAIL PROTECTED]
| Trouble unsubscribing? Try: http://lists.mysql.com/php/unsubscribe.php
| 


-
Before posting, please check:
   http://www.mysql.com/doc/ (the manual)
   http://lists.mysql.com/   (the list archive)

To request this thread, e-mail [EMAIL PROTECTED]
To unsubscribe, e-mail mysql-unsubscribe-##L=##[EMAIL PROTECTED]
Trouble unsubscribing? Try: http://lists.mysql.com/php/unsubscribe.php




Re: SQL optimization problem

2003-01-11 Thread Ryan Fox
Taking a blind stab, how about..

SELECT a.name, minimum(0,COUNT(b.id)) as votes FROM poll_options as a LEFT
JOIN poll_votes as b on a.id=b.oid
WHERE b.pid='poll_id' GROUP BY b.oid

Ryan Fox

- Original Message -
From: Blaster [EMAIL PROTECTED]

 However! Here comes the problem, if no vote is cast on an option, it will
 not show up in the list! I want it to print 0%
 for any options that havn't received a vote, like it would with my old
 query system. This is basically what I want to
 do:

 SELECT a.name, COUNT(b.id) as votes FROM poll_options as a, poll_votes as
b
 WHERE b.pid='poll_id' AND b.oid=a.id GROUP BY b.oid

 With one exception, if votes = 0, it should be listed in the result
aswell!

sql, query


-
Before posting, please check:
   http://www.mysql.com/manual.php   (the manual)
   http://lists.mysql.com/   (the list archive)

To request this thread, e-mail [EMAIL PROTECTED]
To unsubscribe, e-mail [EMAIL PROTECTED]
Trouble unsubscribing? Try: http://lists.mysql.com/php/unsubscribe.php




Search SQL optimization

2002-07-24 Thread Erick Papadakis

Let us say I have two tables tab1 and tab2. 

tab1: 
   col1
   col2

tab2:
   col3
   col4

For my search, a user can enter space delimited words to search, e.g.,

   microsoft windows xp

i have to search for EACH of these words, and join the 2 tables too, so
my sql query looks somewhat like this: 

select * from tab1, tab2 
where
tab1.col1 = tab2.col3 
and  
(
 tab1.col1  = microsoft 
  or tab1.col2  = microsoft 
  or tab1.col1  = windows 
  or tab1.col2  = windows 
  or tab1.col1  = xp
  or tab1.col2  = xp
)
;


now my question is how can i optimize this query? apart from the sql, can
i set some indices which will help me make this faster? 

thanks/erick

__
Do You Yahoo!?
Yahoo! Health - Feel better, live better
http://health.yahoo.com

-
Before posting, please check:
   http://www.mysql.com/manual.php   (the manual)
   http://lists.mysql.com/   (the list archive)

To request this thread, e-mail [EMAIL PROTECTED]
To unsubscribe, e-mail [EMAIL PROTECTED]
Trouble unsubscribing? Try: http://lists.mysql.com/php/unsubscribe.php




SQL optimization

2001-06-29 Thread Dean Ware

Hi, MySQL seems to really under perform when using joins.

Am I doing something wrong?

I have the following query:
SELECT DISTINCT Product.ProductID, Product.Title, ProductFormat.Price, 
ProductFormat.TradePrice, ProductFormat.ProductCode, ProductFormat.Format, 
ShoppingCart.Quantity
 FROM Product
 LEFT JOIN ProductFormat
 ON ProductFormat.ProductID = Product.ProductID
 LEFT JOIN ShoppingCart
 ON ProductFormat.ProductCode = ShoppingCart.ProductCode
 WHERE ShoppingCart.PersonID = 13;

Product has about 1000 rows
ProductFormat has about 2000 rows
ShoppingCart has about 20 rows

Thing is, this query takes on average 3 seconds to return about 4 records!!

my other queries seem to be in the tens of milliseconds.

Thing is, all my queries with JOINS in them exhibit this poor performance.

PersonID is the primary key in ShoppingCart and the big table Product. 
ProductFormat has ProductCode as its primary key.

Is there anything I can do about this?

Thanks in advance


Dean Ware

Web Developer

http://www.readingroom.com
Winner : Best Business to Business Website 2000-01
(Internet Business Awards sponsored by ntl)

Reading Room Ltd.
77 Dean Street
Soho
London
W1D 3SH
UK

Tel: +44 (0) 20 7734 9499
Fax: +44 (0) 20 7439 4190

The information transmitted is intended only for the person or entity to 
which it is addressed and may contain confidential and/or privileged 
material.  Any review, re-transmission, dissemination or other use of, or 
taking of any action in reliance upon, this information by persons or 
entities other than the intended recipient is prohibited.   If you received 
this in error, please contact the sender and delete the material from any 
computer.


-
Before posting, please check:
   http://www.mysql.com/manual.php   (the manual)
   http://lists.mysql.com/   (the list archive)

To request this thread, e-mail [EMAIL PROTECTED]
To unsubscribe, e-mail [EMAIL PROTECTED]
Trouble unsubscribing? Try: http://lists.mysql.com/php/unsubscribe.php