Yes, it can handle one million rows, if designed right.
Make each table (machines and supplies) have an integer as a primary key,
a la
machines_idx INT(10) unsigned not null auto_increment primary key
Then you can create a match table like
CREATE TABLE machines_supplies (
machines_supplies_idx INT(10) unsigned not null auto_increment primary key,
machines INT(10) unsigned not null default 0,
supplies INT(10) unsigned not null default 0,
KEY machines_idx(machines),
KEY supplies_idx(supplies)
);
But it won't REALLY be half a million rows unless MOST supplies map onto each machine. Let's say 100 supplies map onto each machine -- that's only 10,000. That's nothing for a table like the above. If it really were almost-all, you could be clever and make a table of all supplies that did NOT go to a given machine, and invert the set, but even that wouldn't be necessary.
I've had mysql tables at 750k rows which work still basically instantly performing most ops on their indexed fields, so it should be easy. With the above example, just store 1 row, taking the primary key from the respective machine and supplies table, and put those numbers in your lookup table as per above, and it should be lightning fast.