views:

104

answers:

5

How can I count the table size in MySQL or PosgreSQL using a restriction? for example: WHERE organisation_id=1

+1  A: 

If you have associations set up in your models as follows:

class Organisation < ActiveRecord::Base
  has_many :members
end

class Member < ActiveRecord::Base
  belongs_to :organisation
end

then you can find how many members are in organisation 1 with the following:

organisation = Organisation.find(1)
n_members = organisation.members.size

Thanks to ActiveRecord, this kind of thing is database independent.

grifaton
count method will be much faster
fl00r
@fl00r: it is count method. After loading `organisation` it does the same as in my example.
klew
klew, you're right. I've mixed up _length_ and _size_ methods
fl00r
+2  A: 

In PostgreSQL you can't. Data is stored in blocks (normaly 8kb each) and you have no idea in what block the records with "organisation_id=1" are stored. When all records are in one block, it's 8kb. When 100 records are stored in 100 blocks, it's 800kb, but that includes other records as well.

You could do some magic with the hidden column "ctid", but that's a lot of work, not accurate and not very usefull as well. Just use pg_relation_size() to get the entire table, that's what you need. If you need the TOAST-table includes, use pg_total_relation_size().

Frank Heikens
+2  A: 
ModelName.count(:conditions => {:organisation_id => 1})
klew
I think this might be a simple solution, then I can multiply by the number of bytes it requires for each column
Boris Barroso
Hm, I thnik that my answer is wrong. It doesn't give table size, but it counts rows in table.
klew
But... `conditional_table_size = rows * row_size`
Randolpho
@Randolpho: But will there be problems with text and blob fields?
klew
Sure. But since they're not stored in the table itself....
Randolpho
A: 

Even shorter version

ModelName.count(:organisation_id => 1)
KandadaBoggu
+1  A: 

It depends on your table structure. If you have all fixed width fields you can get pretty close. If you have variable width fields the best you will do is an estimate. This is for postgres.

SELECT  pg_total_relation_size('my_table') * i / cnt
FROM (
  SELECT SUM(CASE WHEN organization_id = 1 THEN 1 ELSE 0 END) AS i,
  COUNT(1) AS cnt
  FROM my_table
) sub
Scott Bailey