I tried to re-write your query:
SELECT
DISTINCT ic_data.bucket
FROM
ic_data
INNER JOIN ic_index_buckets ON (ic_index_buckets.sid=ic_data.bucket AND ic_index_buckets.csv=ic_data.csv )
INNER JOIN ic_index_bucketgroups ON ( ..... )
WHERE ( ic_data.csv BETWEEN 3 AND 4 OR ic_data.csv BETWEEN 8 AND 17 OR ic_data.csv BETWEEN 20 AND 21 )
AND value ( = ????? )
GROUP BY ic_data.bucket
ORDER BY SUM( ic_data.value ) DESC
I'm confused by a few things:
1) Why is ic_index_bucketgroups used? How is it related to the other tables?
2) you're not checking "value" for anything in the where clause?
3) Why GROUP BY / ORDER BY if you're using DISTINCT with a single column!
4) There are many missing indexes.