Sad to say, you have presented a nasty problem. There's no magic that can avoid a full table or full index scan for the query you showed us.
Edit Why is simply counting all your rows so miraculously fast? @BillKarwin explained that in his comment. You use the MyISAM storage engine, which maintains the table's overall row count in its metadata and so can satisfy SELECT COUNT(*) FROM mytbl
instantaneously. Once you add a WHERE clause it needs to scan all rows.
Suggestions to improve the situation involve using some sort of summary table. In some other RDBMS SQL this would be called a "materialized view." For example you could create this table:
CREATE TABLE tablecounts AS
SELECT COUNT(*) num, B
FROM mytbl
GROUP BY B;
ALTER TABLE tablecounts ADD UNIQUE INDEX B (B);
Then once in a while, maybe from a recurring EVENT, you update it:
INSERT INTO tablecounts (num, B)
SELECT COUNT(*) num, B
FROM mytbl
GROUP BY B
ON DUPLICATE KEY UPDATE SET num=VALUES(num);
Then your app can do SELECT num FROM tablecounts WHERE B=1
to get the count you mentioned in your question.
This isn't a perfect solution. This count will, of course, become stale as other parts of your application INSERT, UPDATE, or DELETE rows in your original table until you run the event. But you'll get an approximate count very quickly.
Edit If you actually need the detailed results of SELECT A FROM tbl WHERE B = 0
an index on (B, A)
will help your performance by only scanning the relevant rows. If most of your rows have B = 1
the index will help a lot by giving MySql a way to ignore them completely.